xref: /openbsd-src/gnu/usr.bin/binutils/bfd/elf32-m32r.c (revision cf2f2c5620d6d9a4fd01930983c4b9a1f76d7aa3)
1fddef416Sniklas /* M32R-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 #include "elf/m32r.h"
26fddef416Sniklas 
27fddef416Sniklas static bfd_reloc_status_type m32r_elf_10_pcrel_reloc
28fddef416Sniklas   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
29fddef416Sniklas static bfd_reloc_status_type m32r_elf_do_10_pcrel_reloc
30fddef416Sniklas   PARAMS ((bfd *, reloc_howto_type *, asection *,
31fddef416Sniklas 	   bfd_byte *, bfd_vma, asection *, bfd_vma, bfd_vma));
32fddef416Sniklas static bfd_reloc_status_type m32r_elf_hi16_reloc
33fddef416Sniklas   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
34fddef416Sniklas static void m32r_elf_relocate_hi16
35fddef416Sniklas   PARAMS ((bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *,
36fddef416Sniklas 	   bfd_byte *, bfd_vma));
37fddef416Sniklas bfd_reloc_status_type m32r_elf_lo16_reloc
38fddef416Sniklas   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
39f7cc78ecSespie bfd_reloc_status_type m32r_elf_generic_reloc
40f7cc78ecSespie   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
41fddef416Sniklas static bfd_reloc_status_type m32r_elf_sda16_reloc
42fddef416Sniklas   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
43fddef416Sniklas static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
44fddef416Sniklas   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
45fddef416Sniklas static void m32r_info_to_howto_rel
46d2201f2fSdrahn   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
47*cf2f2c56Smiod static void m32r_info_to_howto
48*cf2f2c56Smiod   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
49d2201f2fSdrahn bfd_boolean _bfd_m32r_elf_section_from_bfd_section
50d2201f2fSdrahn   PARAMS ((bfd *, asection *, int *));
51fddef416Sniklas void _bfd_m32r_elf_symbol_processing
52fddef416Sniklas   PARAMS ((bfd *, asymbol *));
53d2201f2fSdrahn static bfd_boolean m32r_elf_add_symbol_hook
54*cf2f2c56Smiod   PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
55fddef416Sniklas 	   const char **, flagword *, asection **, bfd_vma *));
56d2201f2fSdrahn static bfd_boolean m32r_elf_relocate_section
57fddef416Sniklas   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
58fddef416Sniklas 	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
59fddef416Sniklas #if 0 /* not yet */
60d2201f2fSdrahn static bfd_boolean m32r_elf_relax_delete_bytes
61fddef416Sniklas   PARAMS ((bfd *, asection *, bfd_vma, int));
62fddef416Sniklas #endif
63f7cc78ecSespie static bfd_reloc_status_type m32r_elf_final_sda_base
64f7cc78ecSespie   PARAMS ((bfd *, struct bfd_link_info *, const char **, bfd_vma *));
65d2201f2fSdrahn static bfd_boolean m32r_elf_object_p
66f7cc78ecSespie   PARAMS ((bfd *));
67f7cc78ecSespie static void m32r_elf_final_write_processing
68d2201f2fSdrahn   PARAMS ((bfd *, bfd_boolean));
69d2201f2fSdrahn static bfd_boolean m32r_elf_set_private_flags
70f7cc78ecSespie   PARAMS ((bfd *, flagword));
71d2201f2fSdrahn static bfd_boolean m32r_elf_merge_private_bfd_data
72f7cc78ecSespie   PARAMS ((bfd *, bfd *));
73d2201f2fSdrahn static bfd_boolean m32r_elf_print_private_bfd_data
74f7cc78ecSespie   PARAMS ((bfd *, PTR));
75d2201f2fSdrahn static bfd_boolean m32r_elf_gc_sweep_hook
76d2201f2fSdrahn   PARAMS ((bfd *, struct bfd_link_info *, asection *,
77d2201f2fSdrahn 	   const Elf_Internal_Rela *));
78d2201f2fSdrahn static bfd_boolean m32r_elf_check_relocs
79d2201f2fSdrahn   PARAMS ((bfd *, struct bfd_link_info *, asection *,
80d2201f2fSdrahn 	   const Elf_Internal_Rela *));
81d2201f2fSdrahn 
82*cf2f2c56Smiod static bfd_boolean m32r_elf_adjust_dynamic_symbol
83*cf2f2c56Smiod   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
84*cf2f2c56Smiod static bfd_boolean m32r_elf_size_dynamic_sections
85*cf2f2c56Smiod   PARAMS ((bfd *, struct bfd_link_info *));
86*cf2f2c56Smiod 
87d2201f2fSdrahn asection * m32r_elf_gc_mark_hook
88d2201f2fSdrahn   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
89d2201f2fSdrahn 	   struct elf_link_hash_entry *, Elf_Internal_Sym *));
90f7cc78ecSespie 
91*cf2f2c56Smiod static bfd_boolean m32r_elf_create_dynamic_sections
92*cf2f2c56Smiod   PARAMS ((bfd *, struct bfd_link_info *));
93*cf2f2c56Smiod 
94*cf2f2c56Smiod static bfd_boolean m32r_elf_finish_dynamic_sections
95*cf2f2c56Smiod   PARAMS ((bfd *, struct bfd_link_info *));
96*cf2f2c56Smiod 
97*cf2f2c56Smiod static bfd_boolean m32r_elf_finish_dynamic_symbol
98*cf2f2c56Smiod   PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
99*cf2f2c56Smiod            Elf_Internal_Sym *));
100*cf2f2c56Smiod 
101*cf2f2c56Smiod static bfd_boolean allocate_dynrelocs
102*cf2f2c56Smiod   PARAMS ((struct elf_link_hash_entry *, PTR));
103*cf2f2c56Smiod static bfd_boolean readonly_dynrelocs
104*cf2f2c56Smiod   PARAMS ((struct elf_link_hash_entry *, PTR));
105*cf2f2c56Smiod static enum elf_reloc_type_class m32r_elf_reloc_type_class
106*cf2f2c56Smiod   PARAMS ((const Elf_Internal_Rela *));
107*cf2f2c56Smiod static bfd_boolean m32r_elf_fake_sections
108*cf2f2c56Smiod   PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
109*cf2f2c56Smiod 
110f7cc78ecSespie #define NOP_INSN		0x7000
111f7cc78ecSespie #define MAKE_PARALLEL(insn)	((insn) | 0x8000)
112f7cc78ecSespie 
113fddef416Sniklas /* Use REL instead of RELA to save space.
114fddef416Sniklas    This only saves space in libraries and object files, but perhaps
115fddef416Sniklas    relocs will be put in ROM?  All in all though, REL relocs are a pain
116fddef416Sniklas    to work with.  */
117*cf2f2c56Smiod /* #define USE_REL	1
118d2201f2fSdrahn 
119d2201f2fSdrahn #ifndef USE_REL
120d2201f2fSdrahn #define USE_REL	0
121*cf2f2c56Smiod #endif */
122*cf2f2c56Smiod /* Use RELA. But use REL to link old objects for backwords compatibility. */
123*cf2f2c56Smiod 
124*cf2f2c56Smiod /* Functions for the M32R ELF linker.  */
125*cf2f2c56Smiod 
126*cf2f2c56Smiod /* The name of the dynamic interpreter.  This is put in the .interp
127*cf2f2c56Smiod    section.  */
128*cf2f2c56Smiod 
129*cf2f2c56Smiod #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
130*cf2f2c56Smiod 
131*cf2f2c56Smiod /* The nop opcode we use.  */
132*cf2f2c56Smiod 
133*cf2f2c56Smiod #define M32R_NOP 0x7000f000
134*cf2f2c56Smiod 
135*cf2f2c56Smiod #define PLT_EMPTY   0x10101010  /* RIE  -> RIE */
136*cf2f2c56Smiod 
137*cf2f2c56Smiod /* The size in bytes of an entry in the procedure linkage table.  */
138*cf2f2c56Smiod 
139*cf2f2c56Smiod #define PLT_ENTRY_SIZE 20
140*cf2f2c56Smiod #define PLT_HEADER_SIZE 20
141*cf2f2c56Smiod 
142*cf2f2c56Smiod /* The first one entries in a procedure linkage table are reserved,
143*cf2f2c56Smiod    and the initial contents are unimportant (we zero them out).
144*cf2f2c56Smiod    Subsequent entries look like this. */
145*cf2f2c56Smiod 
146*cf2f2c56Smiod #define PLT0_ENTRY_WORD0  0xd6c00000    /* seth r6, #high(.got+4)          */
147*cf2f2c56Smiod #define PLT0_ENTRY_WORD1  0x86e60000    /* or3  r6, r6, #low(.got)+4)      */
148*cf2f2c56Smiod #define PLT0_ENTRY_WORD2  0x24e626c6    /* ld   r4, @r6+    -> ld r6, @r6  */
149*cf2f2c56Smiod #define PLT0_ENTRY_WORD3  0x1fc6f000    /* jmp  r6          || pnop        */
150*cf2f2c56Smiod #define PLT0_ENTRY_WORD4  PLT_EMPTY     /* RIE             -> RIE          */
151*cf2f2c56Smiod 
152*cf2f2c56Smiod #define PLT0_PIC_ENTRY_WORD0  0xa4cc0004 /* ld   r4, @(4,r12)              */
153*cf2f2c56Smiod #define PLT0_PIC_ENTRY_WORD1  0xa6cc0008 /* ld   r6, @(8,r12)              */
154*cf2f2c56Smiod #define PLT0_PIC_ENTRY_WORD2  0x1fc6f000 /* jmp  r6         || nop         */
155*cf2f2c56Smiod #define PLT0_PIC_ENTRY_WORD3  PLT_EMPTY  /* RIE             -> RIE         */
156*cf2f2c56Smiod #define PLT0_PIC_ENTRY_WORD4  PLT_EMPTY  /* RIE             -> RIE         */
157*cf2f2c56Smiod 
158*cf2f2c56Smiod #define PLT_ENTRY_WORD0  0xe6000000 /* ld24 r6, .name_in_GOT                */
159*cf2f2c56Smiod #define PLT_ENTRY_WORD1  0x06acf000 /* add  r6, r12          || nop         */
160*cf2f2c56Smiod #define PLT_ENTRY_WORD0b 0xd6c00000 /* seth r6, #high(.name_in_GOT)         */
161*cf2f2c56Smiod #define PLT_ENTRY_WORD1b 0x86e60000 /* or3  r6, r6, #low(.name_in_GOT)      */
162*cf2f2c56Smiod #define PLT_ENTRY_WORD2  0x26c61fc6 /* ld  r6, @r6           -> jmp r6      */
163*cf2f2c56Smiod #define PLT_ENTRY_WORD3  0xe5000000 /* ld24 r5, $offset                     */
164*cf2f2c56Smiod #define PLT_ENTRY_WORD4  0xff000000 /* bra  .plt0.                          */
165*cf2f2c56Smiod 
166fddef416Sniklas 
167fddef416Sniklas static reloc_howto_type m32r_elf_howto_table[] =
168fddef416Sniklas {
169fddef416Sniklas   /* This reloc does nothing.  */
170fddef416Sniklas   HOWTO (R_M32R_NONE,		/* type */
171fddef416Sniklas 	 0,			/* rightshift */
172fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
173fddef416Sniklas 	 32,			/* bitsize */
174d2201f2fSdrahn 	 FALSE,			/* pc_relative */
175fddef416Sniklas 	 0,			/* bitpos */
176fddef416Sniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
177fddef416Sniklas 	 bfd_elf_generic_reloc,	/* special_function */
178fddef416Sniklas 	 "R_M32R_NONE",		/* name */
179d2201f2fSdrahn 	 FALSE,			/* partial_inplace */
180fddef416Sniklas 	 0,			/* src_mask */
181fddef416Sniklas 	 0,			/* dst_mask */
182d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
183fddef416Sniklas 
184fddef416Sniklas   /* A 16 bit absolute relocation.  */
185fddef416Sniklas   HOWTO (R_M32R_16,		/* type */
186fddef416Sniklas 	 0,			/* rightshift */
187fddef416Sniklas 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
188fddef416Sniklas 	 16,			/* bitsize */
189d2201f2fSdrahn 	 FALSE,			/* pc_relative */
190fddef416Sniklas 	 0,			/* bitpos */
191fddef416Sniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
192f7cc78ecSespie 	 m32r_elf_generic_reloc,/* special_function */
193fddef416Sniklas 	 "R_M32R_16",		/* name */
194d2201f2fSdrahn 	 TRUE,			/* partial_inplace */
195fddef416Sniklas 	 0xffff,		/* src_mask */
196fddef416Sniklas 	 0xffff,		/* dst_mask */
197d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
198fddef416Sniklas 
199fddef416Sniklas   /* A 32 bit absolute relocation.  */
200fddef416Sniklas   HOWTO (R_M32R_32,		/* type */
201fddef416Sniklas 	 0,			/* rightshift */
202fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
203fddef416Sniklas 	 32,			/* bitsize */
204d2201f2fSdrahn 	 FALSE,			/* pc_relative */
205fddef416Sniklas 	 0,			/* bitpos */
206fddef416Sniklas 	 complain_overflow_bitfield, /* complain_on_overflow */
207f7cc78ecSespie 	 m32r_elf_generic_reloc,/* special_function */
208fddef416Sniklas 	 "R_M32R_32",		/* name */
209d2201f2fSdrahn 	 TRUE,			/* partial_inplace */
210fddef416Sniklas 	 0xffffffff,		/* src_mask */
211fddef416Sniklas 	 0xffffffff,		/* dst_mask */
212d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
213fddef416Sniklas 
214fddef416Sniklas   /* A 24 bit address.  */
215fddef416Sniklas   HOWTO (R_M32R_24,		/* type */
216fddef416Sniklas 	 0,			/* rightshift */
217fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
218fddef416Sniklas 	 24,			/* bitsize */
219d2201f2fSdrahn 	 FALSE,			/* pc_relative */
220fddef416Sniklas 	 0,			/* bitpos */
221fddef416Sniklas 	 complain_overflow_unsigned, /* complain_on_overflow */
222f7cc78ecSespie 	 m32r_elf_generic_reloc,/* special_function */
223fddef416Sniklas 	 "R_M32R_24",		/* name */
224d2201f2fSdrahn 	 TRUE,			/* partial_inplace */
225fddef416Sniklas 	 0xffffff,		/* src_mask */
226fddef416Sniklas 	 0xffffff,		/* dst_mask */
227d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
228fddef416Sniklas 
229fddef416Sniklas   /* An PC Relative 10-bit relocation, shifted by 2.
230fddef416Sniklas      This reloc is complicated because relocations are relative to pc & -4.
231fddef416Sniklas      i.e. branches in the right insn slot use the address of the left insn
232fddef416Sniklas      slot for pc.  */
233fddef416Sniklas   /* ??? It's not clear whether this should have partial_inplace set or not.
234fddef416Sniklas      Branch relaxing in the assembler can store the addend in the insn,
235fddef416Sniklas      and if bfd_install_relocation gets called the addend may get added
236fddef416Sniklas      again.  */
237fddef416Sniklas   HOWTO (R_M32R_10_PCREL,	/* type */
238fddef416Sniklas 	 2,	                /* rightshift */
239fddef416Sniklas 	 1,	                /* size (0 = byte, 1 = short, 2 = long) */
240fddef416Sniklas 	 10,	                /* bitsize */
241d2201f2fSdrahn 	 TRUE,	                /* pc_relative */
242fddef416Sniklas 	 0,	                /* bitpos */
243fddef416Sniklas 	 complain_overflow_signed, /* complain_on_overflow */
244fddef416Sniklas 	 m32r_elf_10_pcrel_reloc, /* special_function */
245fddef416Sniklas 	 "R_M32R_10_PCREL",	/* name */
246d2201f2fSdrahn 	 FALSE,	                /* partial_inplace */
247fddef416Sniklas 	 0xff,		        /* src_mask */
248fddef416Sniklas 	 0xff,   		/* dst_mask */
249d2201f2fSdrahn 	 TRUE),			/* pcrel_offset */
250fddef416Sniklas 
251fddef416Sniklas   /* A relative 18 bit relocation, right shifted by 2.  */
252fddef416Sniklas   HOWTO (R_M32R_18_PCREL,	/* type */
253fddef416Sniklas 	 2,			/* rightshift */
254fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
255f7cc78ecSespie 	 16,			/* bitsize */
256d2201f2fSdrahn 	 TRUE,			/* pc_relative */
257fddef416Sniklas 	 0,			/* bitpos */
258fddef416Sniklas 	 complain_overflow_signed, /* complain_on_overflow */
259fddef416Sniklas 	 bfd_elf_generic_reloc,	/* special_function */
260fddef416Sniklas 	 "R_M32R_18_PCREL",	/* name */
261d2201f2fSdrahn 	 FALSE,			/* partial_inplace */
262fddef416Sniklas 	 0xffff,		/* src_mask */
263fddef416Sniklas 	 0xffff,		/* dst_mask */
264d2201f2fSdrahn 	 TRUE),			/* pcrel_offset */
265fddef416Sniklas 
266fddef416Sniklas   /* A relative 26 bit relocation, right shifted by 2.  */
267fddef416Sniklas   /* ??? It's not clear whether this should have partial_inplace set or not.
268fddef416Sniklas      Branch relaxing in the assembler can store the addend in the insn,
269fddef416Sniklas      and if bfd_install_relocation gets called the addend may get added
270fddef416Sniklas      again.  */
271fddef416Sniklas   HOWTO (R_M32R_26_PCREL,	/* type */
272fddef416Sniklas 	 2,			/* rightshift */
273fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
274fddef416Sniklas 	 26,			/* bitsize */
275d2201f2fSdrahn 	 TRUE,			/* pc_relative */
276fddef416Sniklas 	 0,			/* bitpos */
277fddef416Sniklas 	 complain_overflow_signed, /* complain_on_overflow */
278fddef416Sniklas 	 bfd_elf_generic_reloc,	/* special_function */
279fddef416Sniklas 	 "R_M32R_26_PCREL",	/* name */
280d2201f2fSdrahn 	 FALSE,			/* partial_inplace */
281fddef416Sniklas 	 0xffffff,		/* src_mask */
282fddef416Sniklas 	 0xffffff,		/* dst_mask */
283d2201f2fSdrahn 	 TRUE),			/* pcrel_offset */
284fddef416Sniklas 
285fddef416Sniklas   /* High 16 bits of address when lower 16 is or'd in.  */
286fddef416Sniklas   HOWTO (R_M32R_HI16_ULO,	/* type */
287fddef416Sniklas 	 16,			/* rightshift */
288fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
289fddef416Sniklas 	 16,			/* bitsize */
290d2201f2fSdrahn 	 FALSE,			/* pc_relative */
291fddef416Sniklas 	 0,			/* bitpos */
292fddef416Sniklas 	 complain_overflow_dont, /* complain_on_overflow */
293fddef416Sniklas 	 m32r_elf_hi16_reloc,	/* special_function */
294fddef416Sniklas 	 "R_M32R_HI16_ULO",	/* name */
295d2201f2fSdrahn 	 TRUE,			/* partial_inplace */
296fddef416Sniklas 	 0x0000ffff,		/* src_mask */
297fddef416Sniklas 	 0x0000ffff,		/* dst_mask */
298d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
299fddef416Sniklas 
300fddef416Sniklas   /* High 16 bits of address when lower 16 is added in.  */
301fddef416Sniklas   HOWTO (R_M32R_HI16_SLO,	/* type */
302fddef416Sniklas 	 16,			/* rightshift */
303fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
304fddef416Sniklas 	 16,			/* bitsize */
305d2201f2fSdrahn 	 FALSE,			/* pc_relative */
306fddef416Sniklas 	 0,			/* bitpos */
307fddef416Sniklas 	 complain_overflow_dont, /* complain_on_overflow */
308fddef416Sniklas 	 m32r_elf_hi16_reloc,	/* special_function */
309fddef416Sniklas 	 "R_M32R_HI16_SLO",	/* name */
310d2201f2fSdrahn 	 TRUE,			/* partial_inplace */
311fddef416Sniklas 	 0x0000ffff,		/* src_mask */
312fddef416Sniklas 	 0x0000ffff,		/* dst_mask */
313d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
314fddef416Sniklas 
315fddef416Sniklas   /* Lower 16 bits of address.  */
316fddef416Sniklas   HOWTO (R_M32R_LO16,		/* type */
317fddef416Sniklas 	 0,			/* rightshift */
318fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
319fddef416Sniklas 	 16,			/* bitsize */
320d2201f2fSdrahn 	 FALSE,			/* pc_relative */
321fddef416Sniklas 	 0,			/* bitpos */
322fddef416Sniklas 	 complain_overflow_dont, /* complain_on_overflow */
323fddef416Sniklas 	 m32r_elf_lo16_reloc,	/* special_function */
324fddef416Sniklas 	 "R_M32R_LO16",		/* name */
325d2201f2fSdrahn 	 TRUE,			/* partial_inplace */
326fddef416Sniklas 	 0x0000ffff,		/* src_mask */
327fddef416Sniklas 	 0x0000ffff,		/* dst_mask */
328d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
329fddef416Sniklas 
330fddef416Sniklas   /* Small data area 16 bits offset.  */
331fddef416Sniklas   HOWTO (R_M32R_SDA16,		/* type */
332fddef416Sniklas 	 0,			/* rightshift */
333fddef416Sniklas 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
334fddef416Sniklas 	 16,			/* bitsize */
335d2201f2fSdrahn 	 FALSE,			/* pc_relative */
336fddef416Sniklas 	 0,			/* bitpos */
337fddef416Sniklas 	 complain_overflow_signed, /* complain_on_overflow */
338fddef416Sniklas 	 m32r_elf_sda16_reloc,	/* special_function */
339fddef416Sniklas 	 "R_M32R_SDA16",	/* name */
340d2201f2fSdrahn 	 TRUE,			/* partial_inplace */  /* FIXME: correct? */
341fddef416Sniklas 	 0x0000ffff,		/* src_mask */
342fddef416Sniklas 	 0x0000ffff,		/* dst_mask */
343d2201f2fSdrahn 	 FALSE),		/* pcrel_offset */
344f7cc78ecSespie 
345f7cc78ecSespie   /* GNU extension to record C++ vtable hierarchy */
346f7cc78ecSespie   HOWTO (R_M32R_GNU_VTINHERIT, /* type */
347f7cc78ecSespie          0,                     /* rightshift */
348f7cc78ecSespie          2,                     /* size (0 = byte, 1 = short, 2 = long) */
349f7cc78ecSespie          0,                     /* bitsize */
350d2201f2fSdrahn          FALSE,                 /* pc_relative */
351f7cc78ecSespie          0,                     /* bitpos */
352f7cc78ecSespie          complain_overflow_dont, /* complain_on_overflow */
353f7cc78ecSespie          NULL,                  /* special_function */
354f7cc78ecSespie          "R_M32R_GNU_VTINHERIT", /* name */
355d2201f2fSdrahn          FALSE,                 /* partial_inplace */
356f7cc78ecSespie          0,                     /* src_mask */
357f7cc78ecSespie          0,                     /* dst_mask */
358d2201f2fSdrahn          FALSE),                /* pcrel_offset */
359f7cc78ecSespie 
360f7cc78ecSespie   /* GNU extension to record C++ vtable member usage */
361f7cc78ecSespie   HOWTO (R_M32R_GNU_VTENTRY,     /* type */
362f7cc78ecSespie          0,                     /* rightshift */
363f7cc78ecSespie          2,                     /* size (0 = byte, 1 = short, 2 = long) */
364f7cc78ecSespie          0,                     /* bitsize */
365d2201f2fSdrahn          FALSE,                 /* pc_relative */
366f7cc78ecSespie          0,                     /* bitpos */
367f7cc78ecSespie          complain_overflow_dont, /* complain_on_overflow */
368f7cc78ecSespie          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
369f7cc78ecSespie          "R_M32R_GNU_VTENTRY",   /* name */
370d2201f2fSdrahn          FALSE,                 /* partial_inplace */
371f7cc78ecSespie          0,                     /* src_mask */
372f7cc78ecSespie          0,                     /* dst_mask */
373d2201f2fSdrahn          FALSE),                /* pcrel_offset */
374f7cc78ecSespie 
375*cf2f2c56Smiod   EMPTY_HOWTO (13),
376*cf2f2c56Smiod   EMPTY_HOWTO (14),
377*cf2f2c56Smiod   EMPTY_HOWTO (15),
378*cf2f2c56Smiod   EMPTY_HOWTO (16),
379*cf2f2c56Smiod   EMPTY_HOWTO (17),
380*cf2f2c56Smiod   EMPTY_HOWTO (18),
381*cf2f2c56Smiod   EMPTY_HOWTO (19),
382*cf2f2c56Smiod   EMPTY_HOWTO (20),
383*cf2f2c56Smiod   EMPTY_HOWTO (21),
384*cf2f2c56Smiod   EMPTY_HOWTO (22),
385*cf2f2c56Smiod   EMPTY_HOWTO (23),
386*cf2f2c56Smiod   EMPTY_HOWTO (24),
387*cf2f2c56Smiod   EMPTY_HOWTO (25),
388*cf2f2c56Smiod   EMPTY_HOWTO (26),
389*cf2f2c56Smiod   EMPTY_HOWTO (27),
390*cf2f2c56Smiod   EMPTY_HOWTO (28),
391*cf2f2c56Smiod   EMPTY_HOWTO (29),
392*cf2f2c56Smiod   EMPTY_HOWTO (30),
393*cf2f2c56Smiod   EMPTY_HOWTO (31),
394*cf2f2c56Smiod   EMPTY_HOWTO (32),
395*cf2f2c56Smiod 
396*cf2f2c56Smiod   /* A 16 bit absolute relocation.  */
397*cf2f2c56Smiod   HOWTO (R_M32R_16_RELA,	/* type */
398*cf2f2c56Smiod 	 0,			/* rightshift */
399*cf2f2c56Smiod 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
400*cf2f2c56Smiod 	 16,			/* bitsize */
401*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
402*cf2f2c56Smiod 	 0,			/* bitpos */
403*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
404*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
405*cf2f2c56Smiod 	 "R_M32R_16_RELA",	/* name */
406*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
407*cf2f2c56Smiod 	 0xffff,		/* src_mask */
408*cf2f2c56Smiod 	 0xffff,		/* dst_mask */
409*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
410*cf2f2c56Smiod 
411*cf2f2c56Smiod   /* A 32 bit absolute relocation.  */
412*cf2f2c56Smiod   HOWTO (R_M32R_32_RELA,	/* type */
413*cf2f2c56Smiod 	 0,			/* rightshift */
414*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
415*cf2f2c56Smiod 	 32,			/* bitsize */
416*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
417*cf2f2c56Smiod 	 0,			/* bitpos */
418*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
419*cf2f2c56Smiod 	 bfd_elf_generic_reloc,/* special_function */
420*cf2f2c56Smiod 	 "R_M32R_32_RELA",		/* name */
421*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
422*cf2f2c56Smiod 	 0xffffffff,		/* src_mask */
423*cf2f2c56Smiod 	 0xffffffff,		/* dst_mask */
424*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
425*cf2f2c56Smiod 
426*cf2f2c56Smiod   /* A 24 bit address.  */
427*cf2f2c56Smiod   HOWTO (R_M32R_24_RELA,	/* type */
428*cf2f2c56Smiod 	 0,			/* rightshift */
429*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
430*cf2f2c56Smiod 	 24,			/* bitsize */
431*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
432*cf2f2c56Smiod 	 0,			/* bitpos */
433*cf2f2c56Smiod 	 complain_overflow_unsigned, /* complain_on_overflow */
434*cf2f2c56Smiod 	 bfd_elf_generic_reloc,/* special_function */
435*cf2f2c56Smiod 	 "R_M32R_24_RELA",	/* name */
436*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
437*cf2f2c56Smiod 	 0xffffff,		/* src_mask */
438*cf2f2c56Smiod 	 0xffffff,		/* dst_mask */
439*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
440*cf2f2c56Smiod 
441*cf2f2c56Smiod   HOWTO (R_M32R_10_PCREL_RELA,	/* type */
442*cf2f2c56Smiod 	 2,	                /* rightshift */
443*cf2f2c56Smiod 	 1,	                /* size (0 = byte, 1 = short, 2 = long) */
444*cf2f2c56Smiod 	 10,	                /* bitsize */
445*cf2f2c56Smiod 	 TRUE,	                /* pc_relative */
446*cf2f2c56Smiod 	 0,	                /* bitpos */
447*cf2f2c56Smiod 	 complain_overflow_signed, /* complain_on_overflow */
448*cf2f2c56Smiod 	 m32r_elf_10_pcrel_reloc, /* special_function */
449*cf2f2c56Smiod 	 "R_M32R_10_PCREL_RELA",/* name */
450*cf2f2c56Smiod 	 FALSE,	                /* partial_inplace */
451*cf2f2c56Smiod 	 0xff,		        /* src_mask */
452*cf2f2c56Smiod 	 0xff,   		/* dst_mask */
453*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
454*cf2f2c56Smiod 
455*cf2f2c56Smiod   /* A relative 18 bit relocation, right shifted by 2.  */
456*cf2f2c56Smiod   HOWTO (R_M32R_18_PCREL_RELA,	/* type */
457*cf2f2c56Smiod 	 2,			/* rightshift */
458*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
459*cf2f2c56Smiod 	 16,			/* bitsize */
460*cf2f2c56Smiod 	 TRUE,			/* pc_relative */
461*cf2f2c56Smiod 	 0,			/* bitpos */
462*cf2f2c56Smiod 	 complain_overflow_signed, /* complain_on_overflow */
463*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
464*cf2f2c56Smiod 	 "R_M32R_18_PCREL_RELA",/* name */
465*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
466*cf2f2c56Smiod 	 0xffff,		/* src_mask */
467*cf2f2c56Smiod 	 0xffff,		/* dst_mask */
468*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
469*cf2f2c56Smiod 
470*cf2f2c56Smiod   /* A relative 26 bit relocation, right shifted by 2.  */
471*cf2f2c56Smiod   HOWTO (R_M32R_26_PCREL_RELA,	/* type */
472*cf2f2c56Smiod 	 2,			/* rightshift */
473*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
474*cf2f2c56Smiod 	 26,			/* bitsize */
475*cf2f2c56Smiod 	 TRUE,			/* pc_relative */
476*cf2f2c56Smiod 	 0,			/* bitpos */
477*cf2f2c56Smiod 	 complain_overflow_signed, /* complain_on_overflow */
478*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
479*cf2f2c56Smiod 	 "R_M32R_26_PCREL_RELA",/* name */
480*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
481*cf2f2c56Smiod 	 0xffffff,		/* src_mask */
482*cf2f2c56Smiod 	 0xffffff,		/* dst_mask */
483*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
484*cf2f2c56Smiod 
485*cf2f2c56Smiod   /* High 16 bits of address when lower 16 is or'd in.  */
486*cf2f2c56Smiod   HOWTO (R_M32R_HI16_ULO_RELA,	/* type */
487*cf2f2c56Smiod 	 16,			/* rightshift */
488*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
489*cf2f2c56Smiod 	 16,			/* bitsize */
490*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
491*cf2f2c56Smiod 	 0,			/* bitpos */
492*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
493*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
494*cf2f2c56Smiod 	 "R_M32R_HI16_ULO_RELA",/* name */
495*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
496*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
497*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
498*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
499*cf2f2c56Smiod 
500*cf2f2c56Smiod   /* High 16 bits of address when lower 16 is added in.  */
501*cf2f2c56Smiod   HOWTO (R_M32R_HI16_SLO_RELA,	/* type */
502*cf2f2c56Smiod 	 16,			/* rightshift */
503*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
504*cf2f2c56Smiod 	 16,			/* bitsize */
505*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
506*cf2f2c56Smiod 	 0,			/* bitpos */
507*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
508*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
509*cf2f2c56Smiod 	 "R_M32R_HI16_SLO_RELA",/* name */
510*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
511*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
512*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
513*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
514*cf2f2c56Smiod 
515*cf2f2c56Smiod   /* Lower 16 bits of address.  */
516*cf2f2c56Smiod   HOWTO (R_M32R_LO16_RELA,		/* type */
517*cf2f2c56Smiod 	 0,			/* rightshift */
518*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
519*cf2f2c56Smiod 	 16,			/* bitsize */
520*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
521*cf2f2c56Smiod 	 0,			/* bitpos */
522*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
523*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
524*cf2f2c56Smiod 	 "R_M32R_LO16_RELA",	/* name */
525*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
526*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
527*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
528*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
529*cf2f2c56Smiod 
530*cf2f2c56Smiod   /* Small data area 16 bits offset.  */
531*cf2f2c56Smiod   HOWTO (R_M32R_SDA16_RELA,	/* type */
532*cf2f2c56Smiod 	 0,			/* rightshift */
533*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
534*cf2f2c56Smiod 	 16,			/* bitsize */
535*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
536*cf2f2c56Smiod 	 0,			/* bitpos */
537*cf2f2c56Smiod 	 complain_overflow_signed, /* complain_on_overflow */
538*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
539*cf2f2c56Smiod 	 "R_M32R_SDA16_RELA",	/* name */
540*cf2f2c56Smiod 	 TRUE,			/* partial_inplace */  /* FIXME: correct? */
541*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
542*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
543*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
544*cf2f2c56Smiod 
545*cf2f2c56Smiod   /* GNU extension to record C++ vtable hierarchy */
546*cf2f2c56Smiod   HOWTO (R_M32R_RELA_GNU_VTINHERIT, /* type */
547*cf2f2c56Smiod          0,                     /* rightshift */
548*cf2f2c56Smiod          2,                     /* size (0 = byte, 1 = short, 2 = long) */
549*cf2f2c56Smiod          0,                     /* bitsize */
550*cf2f2c56Smiod          FALSE,                 /* pc_relative */
551*cf2f2c56Smiod          0,                     /* bitpos */
552*cf2f2c56Smiod          complain_overflow_dont, /* complain_on_overflow */
553*cf2f2c56Smiod          NULL,                  /* special_function */
554*cf2f2c56Smiod          "R_M32R_RELA_GNU_VTINHERIT", /* name */
555*cf2f2c56Smiod          FALSE,                 /* partial_inplace */
556*cf2f2c56Smiod          0,                     /* src_mask */
557*cf2f2c56Smiod          0,                     /* dst_mask */
558*cf2f2c56Smiod          FALSE),                /* pcrel_offset */
559*cf2f2c56Smiod 
560*cf2f2c56Smiod   /* GNU extension to record C++ vtable member usage */
561*cf2f2c56Smiod   HOWTO (R_M32R_RELA_GNU_VTENTRY,     /* type */
562*cf2f2c56Smiod          0,                     /* rightshift */
563*cf2f2c56Smiod          2,                     /* size (0 = byte, 1 = short, 2 = long) */
564*cf2f2c56Smiod          0,                     /* bitsize */
565*cf2f2c56Smiod          FALSE,                 /* pc_relative */
566*cf2f2c56Smiod          0,                     /* bitpos */
567*cf2f2c56Smiod          complain_overflow_dont, /* complain_on_overflow */
568*cf2f2c56Smiod          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
569*cf2f2c56Smiod          "R_M32R_RELA_GNU_VTENTRY",   /* name */
570*cf2f2c56Smiod          FALSE,                 /* partial_inplace */
571*cf2f2c56Smiod          0,                     /* src_mask */
572*cf2f2c56Smiod          0,                     /* dst_mask */
573*cf2f2c56Smiod          FALSE),                /* pcrel_offset */
574*cf2f2c56Smiod 
575*cf2f2c56Smiod   EMPTY_HOWTO (45),
576*cf2f2c56Smiod   EMPTY_HOWTO (46),
577*cf2f2c56Smiod   EMPTY_HOWTO (47),
578*cf2f2c56Smiod 
579*cf2f2c56Smiod   /* Like R_M32R_24, but referring to the GOT table entry for
580*cf2f2c56Smiod      the symbol.  */
581*cf2f2c56Smiod   HOWTO (R_M32R_GOT24,		/* type */
582*cf2f2c56Smiod 	 0,			/* rightshift */
583*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
584*cf2f2c56Smiod 	 24,			/* bitsize */
585*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
586*cf2f2c56Smiod 	 0,			/* bitpos */
587*cf2f2c56Smiod 	 complain_overflow_unsigned, /* complain_on_overflow */
588*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
589*cf2f2c56Smiod 	 "R_M32R_GOT24",	/* name */
590*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
591*cf2f2c56Smiod 	 0xffffff,		/* src_mask */
592*cf2f2c56Smiod 	 0xffffff,		/* dst_mask */
593*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
594*cf2f2c56Smiod 
595*cf2f2c56Smiod   /* Like R_M32R_PCREL, but referring to the procedure linkage table
596*cf2f2c56Smiod      entry for the symbol.  */
597*cf2f2c56Smiod   HOWTO (R_M32R_26_PLTREL,	/* type */
598*cf2f2c56Smiod 	 2,			/* rightshift */
599*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
600*cf2f2c56Smiod 	 24,			/* bitsize */
601*cf2f2c56Smiod 	 TRUE,			/* pc_relative */
602*cf2f2c56Smiod 	 0,			/* bitpos */
603*cf2f2c56Smiod 	 complain_overflow_signed, /* complain_on_overflow */
604*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
605*cf2f2c56Smiod 	 "R_M32R_26_PLTREL",	/* name */
606*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
607*cf2f2c56Smiod 	 0xffffff,		/* src_mask */
608*cf2f2c56Smiod 	 0xffffff,		/* dst_mask */
609*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
610*cf2f2c56Smiod 
611*cf2f2c56Smiod   /* This is used only by the dynamic linker.  The symbol should exist
612*cf2f2c56Smiod      both in the object being run and in some shared library.  The
613*cf2f2c56Smiod      dynamic linker copies the data addressed by the symbol from the
614*cf2f2c56Smiod      shared library into the object, because the object being
615*cf2f2c56Smiod      run has to have the data at some particular address.  */
616*cf2f2c56Smiod   HOWTO (R_M32R_COPY,		/* type */
617*cf2f2c56Smiod 	 0,			/* rightshift */
618*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
619*cf2f2c56Smiod 	 32,			/* bitsize */
620*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
621*cf2f2c56Smiod 	 0,			/* bitpos */
622*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
623*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
624*cf2f2c56Smiod 	 "R_M32R_COPY",		/* name */
625*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
626*cf2f2c56Smiod 	 0xffffffff,		/* src_mask */
627*cf2f2c56Smiod 	 0xffffffff,		/* dst_mask */
628*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
629*cf2f2c56Smiod 
630*cf2f2c56Smiod   /* Like R_M32R_24, but used when setting global offset table
631*cf2f2c56Smiod      entries.  */
632*cf2f2c56Smiod   HOWTO (R_M32R_GLOB_DAT,	/* type */
633*cf2f2c56Smiod 	 0,			/* rightshift */
634*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
635*cf2f2c56Smiod 	 32,			/* bitsize */
636*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
637*cf2f2c56Smiod 	 0,			/* bitpos */
638*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
639*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
640*cf2f2c56Smiod 	 "R_M32R_GLOB_DAT",	/* name */
641*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
642*cf2f2c56Smiod 	 0xffffffff,		/* src_mask */
643*cf2f2c56Smiod 	 0xffffffff,		/* dst_mask */
644*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
645*cf2f2c56Smiod 
646*cf2f2c56Smiod   /* Marks a procedure linkage table entry for a symbol.  */
647*cf2f2c56Smiod   HOWTO (R_M32R_JMP_SLOT,	/* type */
648*cf2f2c56Smiod 	 0,			/* rightshift */
649*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
650*cf2f2c56Smiod 	 32,			/* bitsize */
651*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
652*cf2f2c56Smiod 	 0,			/* bitpos */
653*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
654*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
655*cf2f2c56Smiod 	 "R_M32R_JMP_SLOT",	/* name */
656*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
657*cf2f2c56Smiod 	 0xffffffff,		/* src_mask */
658*cf2f2c56Smiod 	 0xffffffff,		/* dst_mask */
659*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
660*cf2f2c56Smiod 
661*cf2f2c56Smiod   /* Used only by the dynamic linker.  When the object is run, this
662*cf2f2c56Smiod      longword is set to the load address of the object, plus the
663*cf2f2c56Smiod      addend.  */
664*cf2f2c56Smiod   HOWTO (R_M32R_RELATIVE,	/* type */
665*cf2f2c56Smiod 	 0,			/* rightshift */
666*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
667*cf2f2c56Smiod 	 32,			/* bitsize */
668*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
669*cf2f2c56Smiod 	 0,			/* bitpos */
670*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
671*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
672*cf2f2c56Smiod 	 "R_M32R_RELATIVE",		/* name */
673*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
674*cf2f2c56Smiod 	 0xffffffff,		/* src_mask */
675*cf2f2c56Smiod 	 0xffffffff,		/* dst_mask */
676*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
677*cf2f2c56Smiod 
678*cf2f2c56Smiod   HOWTO (R_M32R_GOTOFF,	/* type */
679*cf2f2c56Smiod 	 0,			/* rightshift */
680*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
681*cf2f2c56Smiod 	 32,			/* bitsize */
682*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
683*cf2f2c56Smiod 	 0,			/* bitpos */
684*cf2f2c56Smiod 	 complain_overflow_bitfield, /* complain_on_overflow */
685*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
686*cf2f2c56Smiod 	 "R_M32R_GOTOFF",		/* name */
687*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
688*cf2f2c56Smiod 	 0xffffffff,		/* src_mask */
689*cf2f2c56Smiod 	 0xffffffff,		/* dst_mask */
690*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
691*cf2f2c56Smiod 
692*cf2f2c56Smiod   /* An PC Relative 24-bit relocation used when setting PIC offset
693*cf2f2c56Smiod      table register. */
694*cf2f2c56Smiod   HOWTO (R_M32R_GOTPC24,		/* type */
695*cf2f2c56Smiod 	 0,			/* rightshift */
696*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
697*cf2f2c56Smiod 	 24,			/* bitsize */
698*cf2f2c56Smiod 	 TRUE,			/* pc_relative */
699*cf2f2c56Smiod 	 0,			/* bitpos */
700*cf2f2c56Smiod 	 complain_overflow_unsigned, /* complain_on_overflow */
701*cf2f2c56Smiod 	 bfd_elf_generic_reloc, /* special_function */
702*cf2f2c56Smiod 	 "R_M32R_GOTPC24",	/* name */
703*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
704*cf2f2c56Smiod 	 0xffffff,		/* src_mask */
705*cf2f2c56Smiod 	 0xffffff,		/* dst_mask */
706*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
707*cf2f2c56Smiod 
708*cf2f2c56Smiod   /* Like R_M32R_HI16_ULO, but referring to the GOT table entry for
709*cf2f2c56Smiod      the symbol.  */
710*cf2f2c56Smiod   HOWTO (R_M32R_GOT16_HI_ULO,	/* type */
711*cf2f2c56Smiod 	 16,			/* rightshift */
712*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
713*cf2f2c56Smiod 	 16,			/* bitsize */
714*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
715*cf2f2c56Smiod 	 0,			/* bitpos */
716*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
717*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
718*cf2f2c56Smiod 	 "R_M32R_GOT16_HI_ULO",	/* name */
719*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
720*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
721*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
722*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
723*cf2f2c56Smiod 
724*cf2f2c56Smiod   /* Like R_M32R_HI16_SLO, but referring to the GOT table entry for
725*cf2f2c56Smiod      the symbol.  */
726*cf2f2c56Smiod   HOWTO (R_M32R_GOT16_HI_SLO,	/* type */
727*cf2f2c56Smiod 	 16,			/* rightshift */
728*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
729*cf2f2c56Smiod 	 16,			/* bitsize */
730*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
731*cf2f2c56Smiod 	 0,			/* bitpos */
732*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
733*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
734*cf2f2c56Smiod 	 "R_M32R_GOT16_HI_SLO",	/* name */
735*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
736*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
737*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
738*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
739*cf2f2c56Smiod 
740*cf2f2c56Smiod   /* Like R_M32R_LO16, but referring to the GOT table entry for
741*cf2f2c56Smiod      the symbol.  */
742*cf2f2c56Smiod   HOWTO (R_M32R_GOT16_LO,	/* type */
743*cf2f2c56Smiod 	 0,			/* rightshift */
744*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
745*cf2f2c56Smiod 	 16,			/* bitsize */
746*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
747*cf2f2c56Smiod 	 0,			/* bitpos */
748*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
749*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
750*cf2f2c56Smiod 	 "R_M32R_GOT16_LO",	/* name */
751*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
752*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
753*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
754*cf2f2c56Smiod 	 FALSE),		/* pcrel_offset */
755*cf2f2c56Smiod 
756*cf2f2c56Smiod   /* An PC Relative relocation used when setting PIC offset table register.
757*cf2f2c56Smiod      Like R_M32R_HI16_ULO, but referring to the GOT table entry for
758*cf2f2c56Smiod      the symbol.  */
759*cf2f2c56Smiod   HOWTO (R_M32R_GOTPC_HI_ULO,	/* type */
760*cf2f2c56Smiod 	 16,			/* rightshift */
761*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
762*cf2f2c56Smiod 	 16,			/* bitsize */
763*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
764*cf2f2c56Smiod 	 0,			/* bitpos */
765*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
766*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
767*cf2f2c56Smiod 	 "R_M32R_GOTPC_HI_ULO",	/* name */
768*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
769*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
770*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
771*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
772*cf2f2c56Smiod 
773*cf2f2c56Smiod   /* An PC Relative relocation used when setting PIC offset table register.
774*cf2f2c56Smiod      Like R_M32R_HI16_SLO, but referring to the GOT table entry for
775*cf2f2c56Smiod      the symbol.  */
776*cf2f2c56Smiod   HOWTO (R_M32R_GOTPC_HI_SLO,	/* type */
777*cf2f2c56Smiod 	 16,			/* rightshift */
778*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
779*cf2f2c56Smiod 	 16,			/* bitsize */
780*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
781*cf2f2c56Smiod 	 0,			/* bitpos */
782*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
783*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
784*cf2f2c56Smiod 	 "R_M32R_GOTPC_HI_SLO",	/* name */
785*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
786*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
787*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
788*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
789*cf2f2c56Smiod 
790*cf2f2c56Smiod   /* An PC Relative relocation used when setting PIC offset table register.
791*cf2f2c56Smiod      Like R_M32R_LO16, but referring to the GOT table entry for
792*cf2f2c56Smiod      the symbol.  */
793*cf2f2c56Smiod   HOWTO (R_M32R_GOTPC_LO,	/* type */
794*cf2f2c56Smiod 	 0,			/* rightshift */
795*cf2f2c56Smiod 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
796*cf2f2c56Smiod 	 16,			/* bitsize */
797*cf2f2c56Smiod 	 FALSE,			/* pc_relative */
798*cf2f2c56Smiod 	 0,			/* bitpos */
799*cf2f2c56Smiod 	 complain_overflow_dont, /* complain_on_overflow */
800*cf2f2c56Smiod 	 bfd_elf_generic_reloc,	/* special_function */
801*cf2f2c56Smiod 	 "R_M32R_GOTPC_LO",	/* name */
802*cf2f2c56Smiod 	 FALSE,			/* partial_inplace */
803*cf2f2c56Smiod 	 0x0000ffff,		/* src_mask */
804*cf2f2c56Smiod 	 0x0000ffff,		/* dst_mask */
805*cf2f2c56Smiod 	 TRUE),			/* pcrel_offset */
806fddef416Sniklas };
807fddef416Sniklas 
808fddef416Sniklas /* Handle the R_M32R_10_PCREL reloc.  */
809fddef416Sniklas 
810fddef416Sniklas static bfd_reloc_status_type
m32r_elf_10_pcrel_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)811fddef416Sniklas m32r_elf_10_pcrel_reloc (abfd, reloc_entry, symbol, data,
812fddef416Sniklas 			 input_section, output_bfd, error_message)
813fddef416Sniklas      bfd * abfd;
814fddef416Sniklas      arelent * reloc_entry;
815fddef416Sniklas      asymbol * symbol;
816fddef416Sniklas      PTR data;
817fddef416Sniklas      asection * input_section;
818fddef416Sniklas      bfd * output_bfd;
819f7cc78ecSespie      char ** error_message ATTRIBUTE_UNUSED;
820fddef416Sniklas {
821fddef416Sniklas   /* This part is from bfd_elf_generic_reloc.  */
822fddef416Sniklas   if (output_bfd != (bfd *) NULL
823fddef416Sniklas       && (symbol->flags & BSF_SECTION_SYM) == 0
824fddef416Sniklas       && (! reloc_entry->howto->partial_inplace
825fddef416Sniklas 	  || reloc_entry->addend == 0))
826fddef416Sniklas     {
827fddef416Sniklas       reloc_entry->address += input_section->output_offset;
828fddef416Sniklas       return bfd_reloc_ok;
829fddef416Sniklas     }
830fddef416Sniklas 
831fddef416Sniklas   if (output_bfd != NULL)
832fddef416Sniklas     {
833fddef416Sniklas       /* FIXME: See bfd_perform_relocation.  Is this right?  */
834fddef416Sniklas       return bfd_reloc_continue;
835fddef416Sniklas     }
836fddef416Sniklas 
837fddef416Sniklas   return m32r_elf_do_10_pcrel_reloc (abfd, reloc_entry->howto,
838fddef416Sniklas 				     input_section,
839fddef416Sniklas 				     data, reloc_entry->address,
840fddef416Sniklas 				     symbol->section,
841fddef416Sniklas 				     (symbol->value
842fddef416Sniklas 				      + symbol->section->output_section->vma
843fddef416Sniklas 				      + symbol->section->output_offset),
844fddef416Sniklas 				     reloc_entry->addend);
845fddef416Sniklas }
846fddef416Sniklas 
847fddef416Sniklas /* Utility to actually perform an R_M32R_10_PCREL reloc.  */
848fddef416Sniklas 
849fddef416Sniklas static bfd_reloc_status_type
m32r_elf_do_10_pcrel_reloc(abfd,howto,input_section,data,offset,symbol_section,symbol_value,addend)850fddef416Sniklas m32r_elf_do_10_pcrel_reloc (abfd, howto, input_section, data, offset,
851fddef416Sniklas 			    symbol_section, symbol_value, addend)
852fddef416Sniklas      bfd *abfd;
853fddef416Sniklas      reloc_howto_type *howto;
854fddef416Sniklas      asection *input_section;
855fddef416Sniklas      bfd_byte *data;
856fddef416Sniklas      bfd_vma offset;
857f7cc78ecSespie      asection *symbol_section ATTRIBUTE_UNUSED;
858fddef416Sniklas      bfd_vma symbol_value;
859fddef416Sniklas      bfd_vma addend;
860fddef416Sniklas {
861fddef416Sniklas   bfd_signed_vma relocation;
862fddef416Sniklas   unsigned long x;
863fddef416Sniklas   bfd_reloc_status_type status;
864fddef416Sniklas 
865fddef416Sniklas   /* Sanity check the address (offset in section).  */
866fddef416Sniklas   if (offset > input_section->_cooked_size)
867fddef416Sniklas     return bfd_reloc_outofrange;
868fddef416Sniklas 
869fddef416Sniklas   relocation = symbol_value + addend;
870fddef416Sniklas   /* Make it pc relative.  */
871fddef416Sniklas   relocation -=	(input_section->output_section->vma
872fddef416Sniklas 		 + input_section->output_offset);
873fddef416Sniklas   /* These jumps mask off the lower two bits of the current address
874fddef416Sniklas      before doing pcrel calculations.  */
875d2201f2fSdrahn   relocation -= (offset & -(bfd_vma) 4);
876fddef416Sniklas 
877fddef416Sniklas   if (relocation < -0x200 || relocation > 0x1ff)
878fddef416Sniklas     status = bfd_reloc_overflow;
879fddef416Sniklas   else
880fddef416Sniklas     status = bfd_reloc_ok;
881fddef416Sniklas 
882fddef416Sniklas   x = bfd_get_16 (abfd, data + offset);
883fddef416Sniklas   relocation >>= howto->rightshift;
884fddef416Sniklas   relocation <<= howto->bitpos;
885fddef416Sniklas   x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask);
886d2201f2fSdrahn   bfd_put_16 (abfd, (bfd_vma) x, data + offset);
887fddef416Sniklas 
888fddef416Sniklas   return status;
889fddef416Sniklas }
890fddef416Sniklas 
891fddef416Sniklas /* Handle the R_M32R_HI16_[SU]LO relocs.
892fddef416Sniklas    HI16_SLO is for the add3 and load/store with displacement instructions.
893fddef416Sniklas    HI16_ULO is for the or3 instruction.
894fddef416Sniklas    For R_M32R_HI16_SLO, the lower 16 bits are sign extended when added to
895fddef416Sniklas    the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then
896fddef416Sniklas    we must add one to the high 16 bytes (which will get subtracted off when
897fddef416Sniklas    the low 16 bits are added).
898fddef416Sniklas    These relocs have to be done in combination with an R_M32R_LO16 reloc
899fddef416Sniklas    because there is a carry from the LO16 to the HI16.  Here we just save
900fddef416Sniklas    the information we need; we do the actual relocation when we see the LO16.
901fddef416Sniklas    This code is copied from the elf32-mips.c.  We also support an arbitrary
902fddef416Sniklas    number of HI16 relocs to be associated with a single LO16 reloc.  The
903fddef416Sniklas    assembler sorts the relocs to ensure each HI16 immediately precedes its
904fddef416Sniklas    LO16.  However if there are multiple copies, the assembler may not find
905fddef416Sniklas    the real LO16 so it picks the first one it finds.  */
906fddef416Sniklas 
907fddef416Sniklas struct m32r_hi16
908fddef416Sniklas {
909fddef416Sniklas   struct m32r_hi16 *next;
910fddef416Sniklas   bfd_byte *addr;
911fddef416Sniklas   bfd_vma addend;
912fddef416Sniklas };
913fddef416Sniklas 
914fddef416Sniklas /* FIXME: This should not be a static variable.  */
915fddef416Sniklas 
916fddef416Sniklas static struct m32r_hi16 *m32r_hi16_list;
917fddef416Sniklas 
918fddef416Sniklas static bfd_reloc_status_type
m32r_elf_hi16_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)919fddef416Sniklas m32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
920fddef416Sniklas 		     input_section, output_bfd, error_message)
921f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
922fddef416Sniklas      arelent *reloc_entry;
923fddef416Sniklas      asymbol *symbol;
924fddef416Sniklas      PTR data;
925fddef416Sniklas      asection *input_section;
926fddef416Sniklas      bfd *output_bfd;
927f7cc78ecSespie      char **error_message ATTRIBUTE_UNUSED;
928fddef416Sniklas {
929fddef416Sniklas   bfd_reloc_status_type ret;
930fddef416Sniklas   bfd_vma relocation;
931fddef416Sniklas   struct m32r_hi16 *n;
932fddef416Sniklas 
933fddef416Sniklas   /* This part is from bfd_elf_generic_reloc.
934fddef416Sniklas      If we're relocating, and this an external symbol, we don't want
935fddef416Sniklas      to change anything.  */
936fddef416Sniklas   if (output_bfd != (bfd *) NULL
937fddef416Sniklas       && (symbol->flags & BSF_SECTION_SYM) == 0
938fddef416Sniklas       && reloc_entry->addend == 0)
939fddef416Sniklas     {
940fddef416Sniklas       reloc_entry->address += input_section->output_offset;
941fddef416Sniklas       return bfd_reloc_ok;
942fddef416Sniklas     }
943fddef416Sniklas 
944fddef416Sniklas   /* Sanity check the address (offset in section).  */
945fddef416Sniklas   if (reloc_entry->address > input_section->_cooked_size)
946fddef416Sniklas     return bfd_reloc_outofrange;
947fddef416Sniklas 
948fddef416Sniklas   ret = bfd_reloc_ok;
949fddef416Sniklas   if (bfd_is_und_section (symbol->section)
950fddef416Sniklas       && output_bfd == (bfd *) NULL)
951fddef416Sniklas     ret = bfd_reloc_undefined;
952fddef416Sniklas 
953fddef416Sniklas   if (bfd_is_com_section (symbol->section))
954fddef416Sniklas     relocation = 0;
955fddef416Sniklas   else
956fddef416Sniklas     relocation = symbol->value;
957fddef416Sniklas 
958fddef416Sniklas   relocation += symbol->section->output_section->vma;
959fddef416Sniklas   relocation += symbol->section->output_offset;
960fddef416Sniklas   relocation += reloc_entry->addend;
961fddef416Sniklas 
962fddef416Sniklas   /* Save the information, and let LO16 do the actual relocation.  */
963d2201f2fSdrahn   n = (struct m32r_hi16 *) bfd_malloc ((bfd_size_type) sizeof *n);
964fddef416Sniklas   if (n == NULL)
965fddef416Sniklas     return bfd_reloc_outofrange;
966fddef416Sniklas   n->addr = (bfd_byte *) data + reloc_entry->address;
967fddef416Sniklas   n->addend = relocation;
968fddef416Sniklas   n->next = m32r_hi16_list;
969fddef416Sniklas   m32r_hi16_list = n;
970fddef416Sniklas 
971fddef416Sniklas   if (output_bfd != (bfd *) NULL)
972fddef416Sniklas     reloc_entry->address += input_section->output_offset;
973fddef416Sniklas 
974fddef416Sniklas   return ret;
975fddef416Sniklas }
976fddef416Sniklas 
977fddef416Sniklas /* Handle an M32R ELF HI16 reloc.  */
978fddef416Sniklas 
979fddef416Sniklas static void
m32r_elf_relocate_hi16(input_bfd,type,relhi,rello,contents,addend)980fddef416Sniklas m32r_elf_relocate_hi16 (input_bfd, type, relhi, rello, contents, addend)
981fddef416Sniklas      bfd *input_bfd;
982fddef416Sniklas      int type;
983fddef416Sniklas      Elf_Internal_Rela *relhi;
984fddef416Sniklas      Elf_Internal_Rela *rello;
985fddef416Sniklas      bfd_byte *contents;
986fddef416Sniklas      bfd_vma addend;
987fddef416Sniklas {
988fddef416Sniklas   unsigned long insn;
989fddef416Sniklas   bfd_vma addlo;
990fddef416Sniklas 
991fddef416Sniklas   insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
992fddef416Sniklas 
993fddef416Sniklas   addlo = bfd_get_32 (input_bfd, contents + rello->r_offset);
994fddef416Sniklas   if (type == R_M32R_HI16_SLO)
995fddef416Sniklas     addlo = ((addlo & 0xffff) ^ 0x8000) - 0x8000;
996fddef416Sniklas   else
997fddef416Sniklas     addlo &= 0xffff;
998fddef416Sniklas 
999fddef416Sniklas   addend += ((insn & 0xffff) << 16) + addlo;
1000fddef416Sniklas 
1001fddef416Sniklas   /* Reaccount for sign extension of low part.  */
1002fddef416Sniklas   if (type == R_M32R_HI16_SLO
1003fddef416Sniklas       && (addend & 0x8000) != 0)
1004fddef416Sniklas     addend += 0x10000;
1005fddef416Sniklas 
1006fddef416Sniklas   bfd_put_32 (input_bfd,
1007fddef416Sniklas 	      (insn & 0xffff0000) | ((addend >> 16) & 0xffff),
1008fddef416Sniklas 	      contents + relhi->r_offset);
1009fddef416Sniklas }
1010fddef416Sniklas 
1011fddef416Sniklas /* Do an R_M32R_LO16 relocation.  This is a straightforward 16 bit
1012fddef416Sniklas    inplace relocation; this function exists in order to do the
1013fddef416Sniklas    R_M32R_HI16_[SU]LO relocation described above.  */
1014fddef416Sniklas 
1015fddef416Sniklas bfd_reloc_status_type
m32r_elf_lo16_reloc(input_bfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)1016f7cc78ecSespie m32r_elf_lo16_reloc (input_bfd, reloc_entry, symbol, data,
1017fddef416Sniklas 		     input_section, output_bfd, error_message)
1018f7cc78ecSespie      bfd *input_bfd;
1019fddef416Sniklas      arelent *reloc_entry;
1020fddef416Sniklas      asymbol *symbol;
1021fddef416Sniklas      PTR data;
1022fddef416Sniklas      asection *input_section;
1023fddef416Sniklas      bfd *output_bfd;
1024fddef416Sniklas      char **error_message;
1025fddef416Sniklas {
1026f7cc78ecSespie   /* This part is from bfd_elf_generic_reloc.
1027f7cc78ecSespie      If we're relocating, and this an external symbol, we don't want
1028f7cc78ecSespie      to change anything.  */
1029f7cc78ecSespie   if (output_bfd != (bfd *) NULL
1030f7cc78ecSespie       && (symbol->flags & BSF_SECTION_SYM) == 0
1031f7cc78ecSespie       && reloc_entry->addend == 0)
1032f7cc78ecSespie     {
1033f7cc78ecSespie       reloc_entry->address += input_section->output_offset;
1034f7cc78ecSespie       return bfd_reloc_ok;
1035f7cc78ecSespie     }
1036f7cc78ecSespie 
1037fddef416Sniklas   if (m32r_hi16_list != NULL)
1038fddef416Sniklas     {
1039fddef416Sniklas       struct m32r_hi16 *l;
1040fddef416Sniklas 
1041fddef416Sniklas       l = m32r_hi16_list;
1042fddef416Sniklas       while (l != NULL)
1043fddef416Sniklas 	{
1044fddef416Sniklas 	  unsigned long insn;
1045fddef416Sniklas 	  unsigned long val;
1046fddef416Sniklas 	  unsigned long vallo;
1047fddef416Sniklas 	  struct m32r_hi16 *next;
1048fddef416Sniklas 
1049fddef416Sniklas 	  /* Do the HI16 relocation.  Note that we actually don't need
1050fddef416Sniklas 	     to know anything about the LO16 itself, except where to
1051fddef416Sniklas 	     find the low 16 bits of the addend needed by the LO16.  */
1052f7cc78ecSespie 	  insn = bfd_get_32 (input_bfd, l->addr);
1053f7cc78ecSespie 	  vallo = ((bfd_get_32 (input_bfd, (bfd_byte *) data + reloc_entry->address)
1054fddef416Sniklas 		   & 0xffff) ^ 0x8000) - 0x8000;
1055fddef416Sniklas 	  val = ((insn & 0xffff) << 16) + vallo;
1056fddef416Sniklas 	  val += l->addend;
1057fddef416Sniklas 
1058fddef416Sniklas 	  /* Reaccount for sign extension of low part.  */
1059fddef416Sniklas 	  if ((val & 0x8000) != 0)
1060fddef416Sniklas 	    val += 0x10000;
1061fddef416Sniklas 
1062d2201f2fSdrahn 	  insn = (insn &~ (bfd_vma) 0xffff) | ((val >> 16) & 0xffff);
1063d2201f2fSdrahn 	  bfd_put_32 (input_bfd, (bfd_vma) insn, l->addr);
1064fddef416Sniklas 
1065fddef416Sniklas 	  next = l->next;
1066fddef416Sniklas 	  free (l);
1067fddef416Sniklas 	  l = next;
1068fddef416Sniklas 	}
1069fddef416Sniklas 
1070fddef416Sniklas       m32r_hi16_list = NULL;
1071fddef416Sniklas     }
1072fddef416Sniklas 
1073f7cc78ecSespie   /* Now do the LO16 reloc in the usual way.
1074f7cc78ecSespie      ??? It would be nice to call bfd_elf_generic_reloc here,
1075d2201f2fSdrahn      but we have partial_inplace set.  bfd_elf_generic_reloc will
1076f7cc78ecSespie      pass the handling back to bfd_install_relocation which will install
1077f7cc78ecSespie      a section relative addend which is wrong.  */
1078f7cc78ecSespie   return m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
1079fddef416Sniklas 				input_section, output_bfd, error_message);
1080fddef416Sniklas }
1081fddef416Sniklas 
1082f7cc78ecSespie /* Do generic partial_inplace relocation.
1083f7cc78ecSespie    This is a local replacement for bfd_elf_generic_reloc.  */
1084f7cc78ecSespie 
1085f7cc78ecSespie bfd_reloc_status_type
m32r_elf_generic_reloc(input_bfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)1086f7cc78ecSespie m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
1087f7cc78ecSespie 		     input_section, output_bfd, error_message)
1088f7cc78ecSespie      bfd *input_bfd;
1089f7cc78ecSespie      arelent *reloc_entry;
1090f7cc78ecSespie      asymbol *symbol;
1091f7cc78ecSespie      PTR data;
1092f7cc78ecSespie      asection *input_section;
1093f7cc78ecSespie      bfd *output_bfd;
10945f210c2aSfgsch      char **error_message ATTRIBUTE_UNUSED;
1095f7cc78ecSespie {
1096f7cc78ecSespie   bfd_reloc_status_type ret;
1097f7cc78ecSespie   bfd_vma relocation;
1098f7cc78ecSespie   bfd_byte *inplace_address;
1099f7cc78ecSespie 
1100f7cc78ecSespie   /* This part is from bfd_elf_generic_reloc.
1101f7cc78ecSespie      If we're relocating, and this an external symbol, we don't want
1102f7cc78ecSespie      to change anything.  */
1103f7cc78ecSespie   if (output_bfd != (bfd *) NULL
1104f7cc78ecSespie       && (symbol->flags & BSF_SECTION_SYM) == 0
1105f7cc78ecSespie       && reloc_entry->addend == 0)
1106f7cc78ecSespie     {
1107f7cc78ecSespie       reloc_entry->address += input_section->output_offset;
1108f7cc78ecSespie       return bfd_reloc_ok;
1109f7cc78ecSespie     }
1110f7cc78ecSespie 
1111d2201f2fSdrahn   /* Now do the reloc in the usual way.
1112f7cc78ecSespie      ??? It would be nice to call bfd_elf_generic_reloc here,
1113d2201f2fSdrahn      but we have partial_inplace set.  bfd_elf_generic_reloc will
1114f7cc78ecSespie      pass the handling back to bfd_install_relocation which will install
1115f7cc78ecSespie      a section relative addend which is wrong.  */
1116f7cc78ecSespie 
1117f7cc78ecSespie   /* Sanity check the address (offset in section).  */
1118f7cc78ecSespie   if (reloc_entry->address > input_section->_cooked_size)
1119f7cc78ecSespie     return bfd_reloc_outofrange;
1120f7cc78ecSespie 
1121f7cc78ecSespie   ret = bfd_reloc_ok;
1122f7cc78ecSespie   if (bfd_is_und_section (symbol->section)
1123f7cc78ecSespie       && output_bfd == (bfd *) NULL)
1124f7cc78ecSespie     ret = bfd_reloc_undefined;
1125f7cc78ecSespie 
1126f7cc78ecSespie   if (bfd_is_com_section (symbol->section)
1127f7cc78ecSespie       || output_bfd != (bfd *) NULL)
1128f7cc78ecSespie     relocation = 0;
1129f7cc78ecSespie   else
1130f7cc78ecSespie     relocation = symbol->value;
1131f7cc78ecSespie 
1132f7cc78ecSespie   /* Only do this for a final link.  */
1133f7cc78ecSespie   if (output_bfd == (bfd *) NULL)
1134f7cc78ecSespie     {
1135f7cc78ecSespie       relocation += symbol->section->output_section->vma;
1136f7cc78ecSespie       relocation += symbol->section->output_offset;
1137f7cc78ecSespie     }
1138f7cc78ecSespie 
1139f7cc78ecSespie   relocation += reloc_entry->addend;
11405f210c2aSfgsch   inplace_address = (bfd_byte *) data + reloc_entry->address;
1141f7cc78ecSespie 
1142f7cc78ecSespie #define DOIT(x) 					\
1143f7cc78ecSespie   x = ( (x & ~reloc_entry->howto->dst_mask) | 		\
1144f7cc78ecSespie   (((x & reloc_entry->howto->src_mask) +  relocation) &	\
1145f7cc78ecSespie   reloc_entry->howto->dst_mask))
1146f7cc78ecSespie 
1147f7cc78ecSespie   switch (reloc_entry->howto->size)
1148f7cc78ecSespie     {
1149f7cc78ecSespie     case 1:
1150f7cc78ecSespie       {
1151f7cc78ecSespie 	short x = bfd_get_16 (input_bfd, inplace_address);
1152f7cc78ecSespie 	DOIT (x);
1153d2201f2fSdrahn       	bfd_put_16 (input_bfd, (bfd_vma) x, inplace_address);
1154f7cc78ecSespie       }
1155f7cc78ecSespie       break;
1156f7cc78ecSespie     case 2:
1157f7cc78ecSespie       {
1158f7cc78ecSespie 	unsigned long x = bfd_get_32 (input_bfd, inplace_address);
1159f7cc78ecSespie 	DOIT (x);
1160d2201f2fSdrahn       	bfd_put_32 (input_bfd, (bfd_vma)x , inplace_address);
1161f7cc78ecSespie       }
1162f7cc78ecSespie       break;
1163f7cc78ecSespie     default:
1164f7cc78ecSespie       BFD_ASSERT (0);
1165f7cc78ecSespie     }
1166f7cc78ecSespie 
1167f7cc78ecSespie   if (output_bfd != (bfd *) NULL)
1168f7cc78ecSespie     reloc_entry->address += input_section->output_offset;
1169f7cc78ecSespie 
1170f7cc78ecSespie   return ret;
1171f7cc78ecSespie }
1172f7cc78ecSespie 
1173fddef416Sniklas /* Handle the R_M32R_SDA16 reloc.
1174fddef416Sniklas    This reloc is used to compute the address of objects in the small data area
1175fddef416Sniklas    and to perform loads and stores from that area.
1176fddef416Sniklas    The lower 16 bits are sign extended and added to the register specified
1177fddef416Sniklas    in the instruction, which is assumed to point to _SDA_BASE_.  */
1178fddef416Sniklas 
1179fddef416Sniklas static bfd_reloc_status_type
m32r_elf_sda16_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)1180fddef416Sniklas m32r_elf_sda16_reloc (abfd, reloc_entry, symbol, data,
1181fddef416Sniklas 		      input_section, output_bfd, error_message)
1182f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
1183fddef416Sniklas      arelent *reloc_entry;
1184fddef416Sniklas      asymbol *symbol;
1185f7cc78ecSespie      PTR data ATTRIBUTE_UNUSED;
1186fddef416Sniklas      asection *input_section;
1187fddef416Sniklas      bfd *output_bfd;
1188f7cc78ecSespie      char **error_message ATTRIBUTE_UNUSED;
1189fddef416Sniklas {
1190fddef416Sniklas   /* This part is from bfd_elf_generic_reloc.  */
1191fddef416Sniklas   if (output_bfd != (bfd *) NULL
1192fddef416Sniklas       && (symbol->flags & BSF_SECTION_SYM) == 0
1193fddef416Sniklas       && (! reloc_entry->howto->partial_inplace
1194fddef416Sniklas 	  || reloc_entry->addend == 0))
1195fddef416Sniklas     {
1196fddef416Sniklas       reloc_entry->address += input_section->output_offset;
1197fddef416Sniklas       return bfd_reloc_ok;
1198fddef416Sniklas     }
1199fddef416Sniklas 
1200fddef416Sniklas   if (output_bfd != NULL)
1201fddef416Sniklas     {
1202fddef416Sniklas       /* FIXME: See bfd_perform_relocation.  Is this right?  */
1203fddef416Sniklas       return bfd_reloc_continue;
1204fddef416Sniklas     }
1205fddef416Sniklas 
1206fddef416Sniklas   /* FIXME: not sure what to do here yet.  But then again, the linker
1207fddef416Sniklas      may never call us.  */
1208fddef416Sniklas   abort ();
1209fddef416Sniklas }
1210fddef416Sniklas 
1211fddef416Sniklas /* Map BFD reloc types to M32R ELF reloc types.  */
1212fddef416Sniklas 
1213fddef416Sniklas struct m32r_reloc_map
1214fddef416Sniklas {
1215f7cc78ecSespie   bfd_reloc_code_real_type bfd_reloc_val;
1216fddef416Sniklas   unsigned char elf_reloc_val;
1217fddef416Sniklas };
1218fddef416Sniklas 
1219*cf2f2c56Smiod static const struct m32r_reloc_map m32r_reloc_map_old[] =
1220fddef416Sniklas {
1221fddef416Sniklas   { BFD_RELOC_NONE, R_M32R_NONE },
1222fddef416Sniklas   { BFD_RELOC_16, R_M32R_16 },
1223fddef416Sniklas   { BFD_RELOC_32, R_M32R_32 },
1224fddef416Sniklas   { BFD_RELOC_M32R_24, R_M32R_24 },
1225fddef416Sniklas   { BFD_RELOC_M32R_10_PCREL, R_M32R_10_PCREL },
1226fddef416Sniklas   { BFD_RELOC_M32R_18_PCREL, R_M32R_18_PCREL },
1227fddef416Sniklas   { BFD_RELOC_M32R_26_PCREL, R_M32R_26_PCREL },
1228fddef416Sniklas   { BFD_RELOC_M32R_HI16_ULO, R_M32R_HI16_ULO },
1229fddef416Sniklas   { BFD_RELOC_M32R_HI16_SLO, R_M32R_HI16_SLO },
1230fddef416Sniklas   { BFD_RELOC_M32R_LO16, R_M32R_LO16 },
1231fddef416Sniklas   { BFD_RELOC_M32R_SDA16, R_M32R_SDA16 },
1232f7cc78ecSespie   { BFD_RELOC_VTABLE_INHERIT, R_M32R_GNU_VTINHERIT },
1233f7cc78ecSespie   { BFD_RELOC_VTABLE_ENTRY, R_M32R_GNU_VTENTRY },
1234fddef416Sniklas };
1235fddef416Sniklas 
1236*cf2f2c56Smiod static const struct m32r_reloc_map m32r_reloc_map[] =
1237*cf2f2c56Smiod {
1238*cf2f2c56Smiod   { BFD_RELOC_NONE, R_M32R_NONE },
1239*cf2f2c56Smiod   { BFD_RELOC_16, R_M32R_16_RELA },
1240*cf2f2c56Smiod   { BFD_RELOC_32, R_M32R_32_RELA },
1241*cf2f2c56Smiod   { BFD_RELOC_M32R_24, R_M32R_24_RELA },
1242*cf2f2c56Smiod   { BFD_RELOC_M32R_10_PCREL, R_M32R_10_PCREL_RELA },
1243*cf2f2c56Smiod   { BFD_RELOC_M32R_18_PCREL, R_M32R_18_PCREL_RELA },
1244*cf2f2c56Smiod   { BFD_RELOC_M32R_26_PCREL, R_M32R_26_PCREL_RELA },
1245*cf2f2c56Smiod   { BFD_RELOC_M32R_HI16_ULO, R_M32R_HI16_ULO_RELA },
1246*cf2f2c56Smiod   { BFD_RELOC_M32R_HI16_SLO, R_M32R_HI16_SLO_RELA },
1247*cf2f2c56Smiod   { BFD_RELOC_M32R_LO16, R_M32R_LO16_RELA },
1248*cf2f2c56Smiod   { BFD_RELOC_M32R_SDA16, R_M32R_SDA16_RELA },
1249*cf2f2c56Smiod   { BFD_RELOC_VTABLE_INHERIT, R_M32R_RELA_GNU_VTINHERIT },
1250*cf2f2c56Smiod   { BFD_RELOC_VTABLE_ENTRY, R_M32R_RELA_GNU_VTENTRY },
1251*cf2f2c56Smiod 
1252*cf2f2c56Smiod   { BFD_RELOC_M32R_GOT24, R_M32R_GOT24 },
1253*cf2f2c56Smiod   { BFD_RELOC_M32R_26_PLTREL, R_M32R_26_PLTREL },
1254*cf2f2c56Smiod   { BFD_RELOC_M32R_COPY, R_M32R_COPY },
1255*cf2f2c56Smiod   { BFD_RELOC_M32R_GLOB_DAT, R_M32R_GLOB_DAT },
1256*cf2f2c56Smiod   { BFD_RELOC_M32R_JMP_SLOT, R_M32R_JMP_SLOT },
1257*cf2f2c56Smiod   { BFD_RELOC_M32R_RELATIVE, R_M32R_RELATIVE },
1258*cf2f2c56Smiod   { BFD_RELOC_M32R_GOTOFF, R_M32R_GOTOFF },
1259*cf2f2c56Smiod   { BFD_RELOC_M32R_GOTPC24, R_M32R_GOTPC24 },
1260*cf2f2c56Smiod   { BFD_RELOC_M32R_GOT16_HI_ULO, R_M32R_GOT16_HI_ULO },
1261*cf2f2c56Smiod   { BFD_RELOC_M32R_GOT16_HI_SLO, R_M32R_GOT16_HI_SLO },
1262*cf2f2c56Smiod   { BFD_RELOC_M32R_GOT16_LO, R_M32R_GOT16_LO },
1263*cf2f2c56Smiod   { BFD_RELOC_M32R_GOTPC_HI_ULO, R_M32R_GOTPC_HI_ULO },
1264*cf2f2c56Smiod   { BFD_RELOC_M32R_GOTPC_HI_SLO, R_M32R_GOTPC_HI_SLO },
1265*cf2f2c56Smiod   { BFD_RELOC_M32R_GOTPC_LO, R_M32R_GOTPC_LO },
1266*cf2f2c56Smiod };
1267*cf2f2c56Smiod 
1268fddef416Sniklas static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup(abfd,code)1269fddef416Sniklas bfd_elf32_bfd_reloc_type_lookup (abfd, code)
1270f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
1271fddef416Sniklas      bfd_reloc_code_real_type code;
1272fddef416Sniklas {
1273fddef416Sniklas   unsigned int i;
1274fddef416Sniklas 
1275*cf2f2c56Smiod #ifdef USE_M32R_OLD_RELOC
1276*cf2f2c56Smiod   for (i = 0;
1277*cf2f2c56Smiod        i < sizeof (m32r_reloc_map_old) / sizeof (struct m32r_reloc_map);
1278*cf2f2c56Smiod        i++)
1279*cf2f2c56Smiod     {
1280*cf2f2c56Smiod       if (m32r_reloc_map_old[i].bfd_reloc_val == code)
1281*cf2f2c56Smiod 	return &m32r_elf_howto_table[m32r_reloc_map_old[i].elf_reloc_val];
1282*cf2f2c56Smiod     }
1283*cf2f2c56Smiod #else /* ! USE_M32R_OLD_RELOC */
1284*cf2f2c56Smiod 
1285fddef416Sniklas   for (i = 0;
1286fddef416Sniklas        i < sizeof (m32r_reloc_map) / sizeof (struct m32r_reloc_map);
1287fddef416Sniklas        i++)
1288fddef416Sniklas     {
1289fddef416Sniklas       if (m32r_reloc_map[i].bfd_reloc_val == code)
1290fddef416Sniklas 	return &m32r_elf_howto_table[m32r_reloc_map[i].elf_reloc_val];
1291fddef416Sniklas     }
1292*cf2f2c56Smiod #endif
1293fddef416Sniklas 
1294fddef416Sniklas   return NULL;
1295fddef416Sniklas }
1296fddef416Sniklas 
1297fddef416Sniklas /* Set the howto pointer for an M32R ELF reloc.  */
1298fddef416Sniklas 
1299fddef416Sniklas static void
m32r_info_to_howto_rel(abfd,cache_ptr,dst)1300fddef416Sniklas m32r_info_to_howto_rel (abfd, cache_ptr, dst)
1301f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
1302fddef416Sniklas      arelent *cache_ptr;
1303d2201f2fSdrahn      Elf_Internal_Rela *dst;
1304fddef416Sniklas {
1305fddef416Sniklas   unsigned int r_type;
1306fddef416Sniklas 
1307fddef416Sniklas   r_type = ELF32_R_TYPE (dst->r_info);
1308*cf2f2c56Smiod   BFD_ASSERT (ELF32_R_TYPE(dst->r_info) <= (unsigned int) R_M32R_GNU_VTENTRY)
1309fddef416Sniklas   cache_ptr->howto = &m32r_elf_howto_table[r_type];
1310fddef416Sniklas }
1311*cf2f2c56Smiod 
1312*cf2f2c56Smiod static void
m32r_info_to_howto(abfd,cache_ptr,dst)1313*cf2f2c56Smiod m32r_info_to_howto (abfd, cache_ptr, dst)
1314*cf2f2c56Smiod      bfd *abfd ATTRIBUTE_UNUSED;
1315*cf2f2c56Smiod      arelent *cache_ptr;
1316*cf2f2c56Smiod      Elf_Internal_Rela *dst;
1317*cf2f2c56Smiod {
1318*cf2f2c56Smiod   BFD_ASSERT ((ELF32_R_TYPE(dst->r_info) == (unsigned int) R_M32R_NONE)
1319*cf2f2c56Smiod               || ((ELF32_R_TYPE(dst->r_info) > (unsigned int) R_M32R_GNU_VTENTRY)
1320*cf2f2c56Smiod                   && (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_M32R_max)));
1321*cf2f2c56Smiod   cache_ptr->howto = &m32r_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
1322*cf2f2c56Smiod }
1323*cf2f2c56Smiod 
1324fddef416Sniklas 
1325fddef416Sniklas /* Given a BFD section, try to locate the corresponding ELF section
1326fddef416Sniklas    index.  */
1327fddef416Sniklas 
1328d2201f2fSdrahn bfd_boolean
_bfd_m32r_elf_section_from_bfd_section(abfd,sec,retval)1329d2201f2fSdrahn _bfd_m32r_elf_section_from_bfd_section (abfd, sec, retval)
1330f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
1331fddef416Sniklas      asection *sec;
1332fddef416Sniklas      int *retval;
1333fddef416Sniklas {
1334fddef416Sniklas   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1335fddef416Sniklas     {
1336fddef416Sniklas       *retval = SHN_M32R_SCOMMON;
1337d2201f2fSdrahn       return TRUE;
1338fddef416Sniklas     }
1339d2201f2fSdrahn   return FALSE;
1340fddef416Sniklas }
1341fddef416Sniklas 
1342fddef416Sniklas /* M32R ELF uses two common sections.  One is the usual one, and the other
1343fddef416Sniklas    is for small objects.  All the small objects are kept together, and then
1344fddef416Sniklas    referenced via one register, which yields faster assembler code.  It is
1345fddef416Sniklas    up to the compiler to emit an instruction to load the register with
1346fddef416Sniklas    _SDA_BASE.  This is what we use for the small common section.  This
1347fddef416Sniklas    approach is copied from elf32-mips.c.  */
1348fddef416Sniklas static asection m32r_elf_scom_section;
1349fddef416Sniklas static asymbol m32r_elf_scom_symbol;
1350fddef416Sniklas static asymbol *m32r_elf_scom_symbol_ptr;
1351fddef416Sniklas 
1352fddef416Sniklas /* Handle the special M32R section numbers that a symbol may use.  */
1353fddef416Sniklas 
1354fddef416Sniklas void
_bfd_m32r_elf_symbol_processing(abfd,asym)1355fddef416Sniklas _bfd_m32r_elf_symbol_processing (abfd, asym)
1356f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
1357fddef416Sniklas      asymbol *asym;
1358fddef416Sniklas {
1359fddef416Sniklas   elf_symbol_type *elfsym;
1360fddef416Sniklas 
1361fddef416Sniklas   elfsym = (elf_symbol_type *) asym;
1362fddef416Sniklas 
1363fddef416Sniklas   switch (elfsym->internal_elf_sym.st_shndx)
1364fddef416Sniklas     {
1365fddef416Sniklas     case SHN_M32R_SCOMMON:
1366fddef416Sniklas       if (m32r_elf_scom_section.name == NULL)
1367fddef416Sniklas 	{
1368fddef416Sniklas 	  /* Initialize the small common section.  */
1369fddef416Sniklas 	  m32r_elf_scom_section.name = ".scommon";
1370fddef416Sniklas 	  m32r_elf_scom_section.flags = SEC_IS_COMMON;
1371fddef416Sniklas 	  m32r_elf_scom_section.output_section = &m32r_elf_scom_section;
1372fddef416Sniklas 	  m32r_elf_scom_section.symbol = &m32r_elf_scom_symbol;
1373fddef416Sniklas 	  m32r_elf_scom_section.symbol_ptr_ptr = &m32r_elf_scom_symbol_ptr;
1374fddef416Sniklas 	  m32r_elf_scom_symbol.name = ".scommon";
1375fddef416Sniklas 	  m32r_elf_scom_symbol.flags = BSF_SECTION_SYM;
1376fddef416Sniklas 	  m32r_elf_scom_symbol.section = &m32r_elf_scom_section;
1377fddef416Sniklas 	  m32r_elf_scom_symbol_ptr = &m32r_elf_scom_symbol;
1378fddef416Sniklas 	}
1379fddef416Sniklas       asym->section = &m32r_elf_scom_section;
1380fddef416Sniklas       asym->value = elfsym->internal_elf_sym.st_size;
1381fddef416Sniklas       break;
1382fddef416Sniklas     }
1383fddef416Sniklas }
1384fddef416Sniklas 
1385fddef416Sniklas /* Hook called by the linker routine which adds symbols from an object
1386fddef416Sniklas    file.  We must handle the special M32R section numbers here.
1387fddef416Sniklas    We also keep watching for whether we need to create the sdata special
1388fddef416Sniklas    linker sections.  */
1389fddef416Sniklas 
1390d2201f2fSdrahn static bfd_boolean
m32r_elf_add_symbol_hook(abfd,info,sym,namep,flagsp,secp,valp)1391fddef416Sniklas m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1392fddef416Sniklas      bfd *abfd;
1393fddef416Sniklas      struct bfd_link_info *info;
1394*cf2f2c56Smiod      Elf_Internal_Sym *sym;
1395fddef416Sniklas      const char **namep;
1396f7cc78ecSespie      flagword *flagsp ATTRIBUTE_UNUSED;
1397fddef416Sniklas      asection **secp;
1398fddef416Sniklas      bfd_vma *valp;
1399fddef416Sniklas {
1400*cf2f2c56Smiod   if (! info->relocatable
1401fddef416Sniklas       && (*namep)[0] == '_' && (*namep)[1] == 'S'
1402d2201f2fSdrahn       && strcmp (*namep, "_SDA_BASE_") == 0
1403*cf2f2c56Smiod       && is_elf_hash_table (info->hash))
1404fddef416Sniklas     {
1405fddef416Sniklas       /* This is simpler than using _bfd_elf_create_linker_section
1406fddef416Sniklas 	 (our needs are simpler than ppc's needs).  Also
1407fddef416Sniklas 	 _bfd_elf_create_linker_section currently has a bug where if a .sdata
1408fddef416Sniklas 	 section already exists a new one is created that follows it which
1409fddef416Sniklas 	 screws of _SDA_BASE_ address calcs because output_offset != 0.  */
1410fddef416Sniklas       struct elf_link_hash_entry *h;
1411d2201f2fSdrahn       struct bfd_link_hash_entry *bh;
1412fddef416Sniklas       asection *s = bfd_get_section_by_name (abfd, ".sdata");
1413fddef416Sniklas 
1414fddef416Sniklas       /* The following code was cobbled from elf32-ppc.c and elflink.c.  */
1415fddef416Sniklas 
1416fddef416Sniklas       if (s == NULL)
1417fddef416Sniklas 	{
1418d2201f2fSdrahn 	  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1419fddef416Sniklas 			    | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1420fddef416Sniklas 
1421fddef416Sniklas 	  s = bfd_make_section_anyway (abfd, ".sdata");
1422fddef416Sniklas 	  if (s == NULL)
1423d2201f2fSdrahn 	    return FALSE;
1424fddef416Sniklas 	  bfd_set_section_flags (abfd, s, flags);
1425fddef416Sniklas 	  bfd_set_section_alignment (abfd, s, 2);
1426fddef416Sniklas 	}
1427fddef416Sniklas 
1428d2201f2fSdrahn       bh = bfd_link_hash_lookup (info->hash, "_SDA_BASE_",
1429d2201f2fSdrahn 				 FALSE, FALSE, FALSE);
1430fddef416Sniklas 
1431d2201f2fSdrahn       if ((bh == NULL || bh->type == bfd_link_hash_undefined)
1432fddef416Sniklas 	  && !(_bfd_generic_link_add_one_symbol (info,
1433fddef416Sniklas 						 abfd,
1434fddef416Sniklas 						 "_SDA_BASE_",
1435fddef416Sniklas 						 BSF_GLOBAL,
1436fddef416Sniklas 						 s,
1437d2201f2fSdrahn 						 (bfd_vma) 32768,
1438fddef416Sniklas 						 (const char *) NULL,
1439d2201f2fSdrahn 						 FALSE,
1440fddef416Sniklas 						 get_elf_backend_data (abfd)->collect,
1441d2201f2fSdrahn 						 &bh)))
1442d2201f2fSdrahn 	return FALSE;
1443d2201f2fSdrahn       h = (struct elf_link_hash_entry *) bh;
1444fddef416Sniklas       h->type = STT_OBJECT;
1445fddef416Sniklas     }
1446fddef416Sniklas 
1447fddef416Sniklas   switch (sym->st_shndx)
1448fddef416Sniklas     {
1449fddef416Sniklas     case SHN_M32R_SCOMMON:
1450fddef416Sniklas       *secp = bfd_make_section_old_way (abfd, ".scommon");
1451fddef416Sniklas       (*secp)->flags |= SEC_IS_COMMON;
1452fddef416Sniklas       *valp = sym->st_size;
1453fddef416Sniklas       break;
1454fddef416Sniklas     }
1455fddef416Sniklas 
1456d2201f2fSdrahn   return TRUE;
1457fddef416Sniklas }
1458fddef416Sniklas 
1459fddef416Sniklas /* We have to figure out the SDA_BASE value, so that we can adjust the
1460fddef416Sniklas    symbol value correctly.  We look up the symbol _SDA_BASE_ in the output
1461fddef416Sniklas    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
1462fddef416Sniklas    target data.  We don't need to adjust the symbol value for an
1463*cf2f2c56Smiod    external symbol if we are producing relocatable output.  */
1464fddef416Sniklas 
1465fddef416Sniklas static bfd_reloc_status_type
m32r_elf_final_sda_base(output_bfd,info,error_message,psb)1466fddef416Sniklas m32r_elf_final_sda_base (output_bfd, info, error_message, psb)
1467fddef416Sniklas      bfd *output_bfd;
1468fddef416Sniklas      struct bfd_link_info *info;
1469fddef416Sniklas      const char **error_message;
1470fddef416Sniklas      bfd_vma *psb;
1471fddef416Sniklas {
1472fddef416Sniklas   if (elf_gp (output_bfd) == 0)
1473fddef416Sniklas     {
1474fddef416Sniklas       struct bfd_link_hash_entry *h;
1475fddef416Sniklas 
1476d2201f2fSdrahn       h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", FALSE, FALSE, TRUE);
1477fddef416Sniklas       if (h != (struct bfd_link_hash_entry *) NULL
1478fddef416Sniklas 	  && h->type == bfd_link_hash_defined)
1479fddef416Sniklas 	elf_gp (output_bfd) = (h->u.def.value
1480fddef416Sniklas 			       + h->u.def.section->output_section->vma
1481fddef416Sniklas 			       + h->u.def.section->output_offset);
1482fddef416Sniklas       else
1483fddef416Sniklas 	{
1484fddef416Sniklas 	  /* Only get the error once.  */
1485fddef416Sniklas 	  *psb = elf_gp (output_bfd) = 4;
1486fddef416Sniklas 	  *error_message =
1487f7cc78ecSespie 	    (const char *) _("SDA relocation when _SDA_BASE_ not defined");
1488fddef416Sniklas 	  return bfd_reloc_dangerous;
1489fddef416Sniklas 	}
1490fddef416Sniklas     }
1491fddef416Sniklas   *psb = elf_gp (output_bfd);
1492fddef416Sniklas   return bfd_reloc_ok;
1493fddef416Sniklas }
1494fddef416Sniklas 
1495*cf2f2c56Smiod /* Return size of a PLT entry.  */
1496*cf2f2c56Smiod #define elf_m32r_sizeof_plt(info) PLT_ENTRY_SIZE
1497*cf2f2c56Smiod 
1498*cf2f2c56Smiod /* The m32r linker needs to keep track of the number of relocs that it
1499*cf2f2c56Smiod    decides to copy in check_relocs for each symbol.  This is so that
1500*cf2f2c56Smiod    it can discard PC relative relocs if it doesn't need them when
1501*cf2f2c56Smiod    linking with -Bsymbolic.  We store the information in a field
1502*cf2f2c56Smiod    extending the regular ELF linker hash table.  */
1503*cf2f2c56Smiod 
1504*cf2f2c56Smiod /* This structure keeps track of the number of PC relative relocs we
1505*cf2f2c56Smiod    have copied for a given symbol.  */
1506*cf2f2c56Smiod 
1507*cf2f2c56Smiod struct elf_m32r_pcrel_relocs_copied
1508*cf2f2c56Smiod {
1509*cf2f2c56Smiod   /* Next section.  */
1510*cf2f2c56Smiod   struct elf_m32r_pcrel_relocs_copied *next;
1511*cf2f2c56Smiod   /* A section in dynobj.  */
1512*cf2f2c56Smiod   asection *section;
1513*cf2f2c56Smiod   /* Number of relocs copied in this section.  */
1514*cf2f2c56Smiod   bfd_size_type count;
1515*cf2f2c56Smiod };
1516*cf2f2c56Smiod 
1517*cf2f2c56Smiod /* The sh linker needs to keep track of the number of relocs that it
1518*cf2f2c56Smiod    decides to copy as dynamic relocs in check_relocs for each symbol.
1519*cf2f2c56Smiod    This is so that it can later discard them if they are found to be
1520*cf2f2c56Smiod    unnecessary.  We store the information in a field extending the
1521*cf2f2c56Smiod    regular ELF linker hash table.  */
1522*cf2f2c56Smiod 
1523*cf2f2c56Smiod struct elf_m32r_dyn_relocs
1524*cf2f2c56Smiod {
1525*cf2f2c56Smiod   struct elf_m32r_dyn_relocs *next;
1526*cf2f2c56Smiod 
1527*cf2f2c56Smiod   /* The input section of the reloc.  */
1528*cf2f2c56Smiod   asection *sec;
1529*cf2f2c56Smiod 
1530*cf2f2c56Smiod   /* Total number of relocs copied for the input section.  */
1531*cf2f2c56Smiod   bfd_size_type count;
1532*cf2f2c56Smiod 
1533*cf2f2c56Smiod   /* Number of pc-relative relocs copied for the input section.  */
1534*cf2f2c56Smiod   bfd_size_type pc_count;
1535*cf2f2c56Smiod };
1536*cf2f2c56Smiod 
1537*cf2f2c56Smiod 
1538*cf2f2c56Smiod /* m32r ELF linker hash entry.  */
1539*cf2f2c56Smiod 
1540*cf2f2c56Smiod struct elf_m32r_link_hash_entry
1541*cf2f2c56Smiod {
1542*cf2f2c56Smiod   struct elf_link_hash_entry root;
1543*cf2f2c56Smiod 
1544*cf2f2c56Smiod   /* Track dynamic relocs copied for this symbol.  */
1545*cf2f2c56Smiod   struct elf_m32r_dyn_relocs *dyn_relocs;
1546*cf2f2c56Smiod 
1547*cf2f2c56Smiod //  bfd_signed_vma gotplt_refcount;
1548*cf2f2c56Smiod 
1549*cf2f2c56Smiod   /* Number of PC relative relocs copied for this symbol.  */
1550*cf2f2c56Smiod   /* struct elf_m32r_pcrel_relocs_copied *pcrel_relocs_copied;  FIXME */
1551*cf2f2c56Smiod };
1552*cf2f2c56Smiod 
1553*cf2f2c56Smiod /* m32r ELF linker hash table.  */
1554*cf2f2c56Smiod 
1555*cf2f2c56Smiod struct elf_m32r_link_hash_table
1556*cf2f2c56Smiod {
1557*cf2f2c56Smiod   struct elf_link_hash_table root;
1558*cf2f2c56Smiod 
1559*cf2f2c56Smiod   /* Short-cuts to get to dynamic linker sections.  */
1560*cf2f2c56Smiod   asection *sgot;
1561*cf2f2c56Smiod   asection *sgotplt;
1562*cf2f2c56Smiod   asection *srelgot;
1563*cf2f2c56Smiod   asection *splt;
1564*cf2f2c56Smiod   asection *srelplt;
1565*cf2f2c56Smiod   asection *sdynbss;
1566*cf2f2c56Smiod   asection *srelbss;
1567*cf2f2c56Smiod 
1568*cf2f2c56Smiod   /* Small local sym to section mapping cache.  */
1569*cf2f2c56Smiod   struct sym_sec_cache sym_sec;
1570*cf2f2c56Smiod };
1571*cf2f2c56Smiod 
1572*cf2f2c56Smiod /* Traverse an m32r ELF linker hash table.  */
1573*cf2f2c56Smiod 
1574*cf2f2c56Smiod #define m32r_elf_link_hash_traverse(table, func, info)			\
1575*cf2f2c56Smiod   (elf_link_hash_traverse						\
1576*cf2f2c56Smiod    (&(table)->root,							\
1577*cf2f2c56Smiod     (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),	\
1578*cf2f2c56Smiod     (info)))
1579*cf2f2c56Smiod 
1580*cf2f2c56Smiod /* Get the m32r ELF linker hash table from a link_info structure.  */
1581*cf2f2c56Smiod 
1582*cf2f2c56Smiod 
1583*cf2f2c56Smiod #define m32r_elf_hash_table(p) \
1584*cf2f2c56Smiod   ((struct elf_m32r_link_hash_table *) ((p)->hash))
1585*cf2f2c56Smiod 
1586*cf2f2c56Smiod /* Create an entry in an m32r ELF linker hash table.  */
1587*cf2f2c56Smiod static struct bfd_hash_entry *
1588*cf2f2c56Smiod m32r_elf_link_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *,
1589*cf2f2c56Smiod                             const char * );
1590*cf2f2c56Smiod 
1591*cf2f2c56Smiod static struct bfd_hash_entry *
m32r_elf_link_hash_newfunc(entry,table,string)1592*cf2f2c56Smiod m32r_elf_link_hash_newfunc (entry, table, string)
1593*cf2f2c56Smiod      struct bfd_hash_entry *entry;
1594*cf2f2c56Smiod      struct bfd_hash_table *table;
1595*cf2f2c56Smiod      const char *string;
1596*cf2f2c56Smiod {
1597*cf2f2c56Smiod   struct elf_m32r_link_hash_entry *ret =
1598*cf2f2c56Smiod     (struct elf_m32r_link_hash_entry *) entry;
1599*cf2f2c56Smiod 
1600*cf2f2c56Smiod   /* Allocate the structure if it has not already been allocated by a
1601*cf2f2c56Smiod      subclass.  */
1602*cf2f2c56Smiod   if (ret == (struct elf_m32r_link_hash_entry *) NULL)
1603*cf2f2c56Smiod     ret = ((struct elf_m32r_link_hash_entry *)
1604*cf2f2c56Smiod            bfd_hash_allocate (table,
1605*cf2f2c56Smiod                               sizeof (struct elf_m32r_link_hash_entry)));
1606*cf2f2c56Smiod   if (ret == (struct elf_m32r_link_hash_entry *) NULL)
1607*cf2f2c56Smiod     return (struct bfd_hash_entry *) ret;
1608*cf2f2c56Smiod 
1609*cf2f2c56Smiod   /* Call the allocation method of the superclass.  */
1610*cf2f2c56Smiod   ret = ((struct elf_m32r_link_hash_entry *)
1611*cf2f2c56Smiod          _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1612*cf2f2c56Smiod                                      table, string));
1613*cf2f2c56Smiod   if (ret != (struct elf_m32r_link_hash_entry *) NULL)
1614*cf2f2c56Smiod     {
1615*cf2f2c56Smiod       struct elf_m32r_link_hash_entry *eh;
1616*cf2f2c56Smiod 
1617*cf2f2c56Smiod       eh = (struct elf_m32r_link_hash_entry *) ret;
1618*cf2f2c56Smiod       eh->dyn_relocs = NULL;
1619*cf2f2c56Smiod //      eh->gotplt_refcount = 0;
1620*cf2f2c56Smiod       /* eh->pcrel_relocs_copied = NULL; FIXME */
1621*cf2f2c56Smiod     }
1622*cf2f2c56Smiod 
1623*cf2f2c56Smiod   return (struct bfd_hash_entry *) ret;
1624*cf2f2c56Smiod }
1625*cf2f2c56Smiod 
1626*cf2f2c56Smiod /* Create an m32r ELF linker hash table.  */
1627*cf2f2c56Smiod static struct bfd_link_hash_table *m32r_elf_link_hash_table_create (bfd *);
1628*cf2f2c56Smiod 
1629*cf2f2c56Smiod static struct bfd_link_hash_table *
m32r_elf_link_hash_table_create(abfd)1630*cf2f2c56Smiod m32r_elf_link_hash_table_create (abfd)
1631*cf2f2c56Smiod      bfd *abfd;
1632*cf2f2c56Smiod {
1633*cf2f2c56Smiod   struct elf_m32r_link_hash_table *ret;
1634*cf2f2c56Smiod   bfd_size_type amt = sizeof (struct elf_m32r_link_hash_table);
1635*cf2f2c56Smiod 
1636*cf2f2c56Smiod   ret = (struct elf_m32r_link_hash_table *) bfd_malloc (amt);
1637*cf2f2c56Smiod   if (ret == (struct elf_m32r_link_hash_table *) NULL)
1638*cf2f2c56Smiod     return NULL;
1639*cf2f2c56Smiod 
1640*cf2f2c56Smiod   if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
1641*cf2f2c56Smiod                                        m32r_elf_link_hash_newfunc))
1642*cf2f2c56Smiod     {
1643*cf2f2c56Smiod       free (ret);
1644*cf2f2c56Smiod       return NULL;
1645*cf2f2c56Smiod     }
1646*cf2f2c56Smiod 
1647*cf2f2c56Smiod   ret->sgot = NULL;
1648*cf2f2c56Smiod   ret->sgotplt = NULL;
1649*cf2f2c56Smiod   ret->srelgot = NULL;
1650*cf2f2c56Smiod   ret->splt = NULL;
1651*cf2f2c56Smiod   ret->srelplt = NULL;
1652*cf2f2c56Smiod   ret->sdynbss = NULL;
1653*cf2f2c56Smiod   ret->srelbss = NULL;
1654*cf2f2c56Smiod   ret->sym_sec.abfd = NULL;
1655*cf2f2c56Smiod 
1656*cf2f2c56Smiod   return &ret->root.root;
1657*cf2f2c56Smiod }
1658*cf2f2c56Smiod 
1659*cf2f2c56Smiod /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
1660*cf2f2c56Smiod    shortcuts to them in our hash table.  */
1661*cf2f2c56Smiod static bfd_boolean create_got_section (bfd *, struct bfd_link_info *);
1662*cf2f2c56Smiod 
1663*cf2f2c56Smiod static bfd_boolean
create_got_section(dynobj,info)1664*cf2f2c56Smiod create_got_section (dynobj, info)
1665*cf2f2c56Smiod      bfd *dynobj;
1666*cf2f2c56Smiod      struct bfd_link_info *info;
1667*cf2f2c56Smiod {
1668*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
1669*cf2f2c56Smiod 
1670*cf2f2c56Smiod   if (! _bfd_elf_create_got_section (dynobj, info))
1671*cf2f2c56Smiod     return FALSE;
1672*cf2f2c56Smiod 
1673*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
1674*cf2f2c56Smiod   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
1675*cf2f2c56Smiod   htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1676*cf2f2c56Smiod   if (! htab->sgot || ! htab->sgotplt)
1677*cf2f2c56Smiod     abort ();
1678*cf2f2c56Smiod 
1679*cf2f2c56Smiod   htab->srelgot = bfd_make_section (dynobj, ".rela.got");
1680*cf2f2c56Smiod   if (htab->srelgot == NULL
1681*cf2f2c56Smiod       || ! bfd_set_section_flags (dynobj, htab->srelgot,
1682*cf2f2c56Smiod                                   (SEC_ALLOC
1683*cf2f2c56Smiod                                    | SEC_LOAD
1684*cf2f2c56Smiod                                    | SEC_HAS_CONTENTS
1685*cf2f2c56Smiod                                    | SEC_IN_MEMORY
1686*cf2f2c56Smiod                                    | SEC_LINKER_CREATED
1687*cf2f2c56Smiod                                    | SEC_READONLY))
1688*cf2f2c56Smiod       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
1689*cf2f2c56Smiod     return FALSE;
1690*cf2f2c56Smiod 
1691*cf2f2c56Smiod   return TRUE;
1692*cf2f2c56Smiod }
1693*cf2f2c56Smiod 
1694*cf2f2c56Smiod /* Create dynamic sections when linking against a dynamic object.  */
1695*cf2f2c56Smiod 
1696*cf2f2c56Smiod static bfd_boolean
m32r_elf_create_dynamic_sections(abfd,info)1697*cf2f2c56Smiod m32r_elf_create_dynamic_sections (abfd, info)
1698*cf2f2c56Smiod      bfd *abfd;
1699*cf2f2c56Smiod      struct bfd_link_info *info;
1700*cf2f2c56Smiod {
1701*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
1702*cf2f2c56Smiod   flagword flags, pltflags;
1703*cf2f2c56Smiod   register asection *s;
1704*cf2f2c56Smiod   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1705*cf2f2c56Smiod   int ptralign = 2; /* 32bit */
1706*cf2f2c56Smiod 
1707*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
1708*cf2f2c56Smiod 
1709*cf2f2c56Smiod   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
1710*cf2f2c56Smiod      .rel[a].bss sections.  */
1711*cf2f2c56Smiod 
1712*cf2f2c56Smiod   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1713*cf2f2c56Smiod            | SEC_LINKER_CREATED);
1714*cf2f2c56Smiod 
1715*cf2f2c56Smiod   pltflags = flags;
1716*cf2f2c56Smiod   pltflags |= SEC_CODE;
1717*cf2f2c56Smiod   if (bed->plt_not_loaded)
1718*cf2f2c56Smiod     pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
1719*cf2f2c56Smiod   if (bed->plt_readonly)
1720*cf2f2c56Smiod     pltflags |= SEC_READONLY;
1721*cf2f2c56Smiod 
1722*cf2f2c56Smiod   s = bfd_make_section (abfd, ".plt");
1723*cf2f2c56Smiod   htab->splt = s;
1724*cf2f2c56Smiod   if (s == NULL
1725*cf2f2c56Smiod       || ! bfd_set_section_flags (abfd, s, pltflags)
1726*cf2f2c56Smiod       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
1727*cf2f2c56Smiod     return FALSE;
1728*cf2f2c56Smiod 
1729*cf2f2c56Smiod   if (bed->want_plt_sym)
1730*cf2f2c56Smiod     {
1731*cf2f2c56Smiod       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
1732*cf2f2c56Smiod          .plt section.  */
1733*cf2f2c56Smiod       struct bfd_link_hash_entry *bh = NULL;
1734*cf2f2c56Smiod       struct elf_link_hash_entry *h;
1735*cf2f2c56Smiod       if (! (_bfd_generic_link_add_one_symbol
1736*cf2f2c56Smiod              (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
1737*cf2f2c56Smiod               (bfd_vma) 0, (const char *) NULL, FALSE,
1738*cf2f2c56Smiod               get_elf_backend_data (abfd)->collect, &bh)))
1739*cf2f2c56Smiod         return FALSE;
1740*cf2f2c56Smiod       h = (struct elf_link_hash_entry *) bh;
1741*cf2f2c56Smiod       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1742*cf2f2c56Smiod       h->type = STT_OBJECT;
1743*cf2f2c56Smiod 
1744*cf2f2c56Smiod       if (info->shared
1745*cf2f2c56Smiod           && ! bfd_elf_link_record_dynamic_symbol (info, h))
1746*cf2f2c56Smiod         return FALSE;
1747*cf2f2c56Smiod     }
1748*cf2f2c56Smiod 
1749*cf2f2c56Smiod   s = bfd_make_section (abfd,
1750*cf2f2c56Smiod                         bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
1751*cf2f2c56Smiod   htab->srelplt = s;
1752*cf2f2c56Smiod   if (s == NULL
1753*cf2f2c56Smiod       || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
1754*cf2f2c56Smiod       || ! bfd_set_section_alignment (abfd, s, ptralign))
1755*cf2f2c56Smiod     return FALSE;
1756*cf2f2c56Smiod 
1757*cf2f2c56Smiod   if (htab->sgot == NULL
1758*cf2f2c56Smiod       && ! create_got_section (abfd, info))
1759*cf2f2c56Smiod     return FALSE;
1760*cf2f2c56Smiod 
1761*cf2f2c56Smiod   {
1762*cf2f2c56Smiod     const char *secname;
1763*cf2f2c56Smiod     char *relname;
1764*cf2f2c56Smiod     flagword secflags;
1765*cf2f2c56Smiod     asection *sec;
1766*cf2f2c56Smiod 
1767*cf2f2c56Smiod     for (sec = abfd->sections; sec; sec = sec->next)
1768*cf2f2c56Smiod       {
1769*cf2f2c56Smiod         secflags = bfd_get_section_flags (abfd, sec);
1770*cf2f2c56Smiod         if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
1771*cf2f2c56Smiod             || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
1772*cf2f2c56Smiod           continue;
1773*cf2f2c56Smiod         secname = bfd_get_section_name (abfd, sec);
1774*cf2f2c56Smiod         relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6);
1775*cf2f2c56Smiod         strcpy (relname, ".rela");
1776*cf2f2c56Smiod         strcat (relname, secname);
1777*cf2f2c56Smiod         if (bfd_get_section_by_name (abfd, secname))
1778*cf2f2c56Smiod           continue;
1779*cf2f2c56Smiod         s = bfd_make_section (abfd, relname);
1780*cf2f2c56Smiod         if (s == NULL
1781*cf2f2c56Smiod             || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
1782*cf2f2c56Smiod             || ! bfd_set_section_alignment (abfd, s, ptralign))
1783*cf2f2c56Smiod           return FALSE;
1784*cf2f2c56Smiod       }
1785*cf2f2c56Smiod   }
1786*cf2f2c56Smiod 
1787*cf2f2c56Smiod   if (bed->want_dynbss)
1788*cf2f2c56Smiod     {
1789*cf2f2c56Smiod       /* The .dynbss section is a place to put symbols which are defined
1790*cf2f2c56Smiod          by dynamic objects, are referenced by regular objects, and are
1791*cf2f2c56Smiod          not functions.  We must allocate space for them in the process
1792*cf2f2c56Smiod          image and use a R_*_COPY reloc to tell the dynamic linker to
1793*cf2f2c56Smiod          initialize them at run time.  The linker script puts the .dynbss
1794*cf2f2c56Smiod          section into the .bss section of the final image.  */
1795*cf2f2c56Smiod       s = bfd_make_section (abfd, ".dynbss");
1796*cf2f2c56Smiod       htab->sdynbss = s;
1797*cf2f2c56Smiod       if (s == NULL
1798*cf2f2c56Smiod           || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
1799*cf2f2c56Smiod         return FALSE;
1800*cf2f2c56Smiod       /* The .rel[a].bss section holds copy relocs.  This section is not
1801*cf2f2c56Smiod          normally needed.  We need to create it here, though, so that the
1802*cf2f2c56Smiod          linker will map it to an output section.  We can't just create it
1803*cf2f2c56Smiod          only if we need it, because we will not know whether we need it
1804*cf2f2c56Smiod          until we have seen all the input files, and the first time the
1805*cf2f2c56Smiod          main linker code calls BFD after examining all the input files
1806*cf2f2c56Smiod          (size_dynamic_sections) the input sections have already been
1807*cf2f2c56Smiod          mapped to the output sections.  If the section turns out not to
1808*cf2f2c56Smiod          be needed, we can discard it later.  We will never need this
1809*cf2f2c56Smiod          section when generating a shared object, since they do not use
1810*cf2f2c56Smiod          copy relocs.  */
1811*cf2f2c56Smiod       if (! info->shared)
1812*cf2f2c56Smiod         {
1813*cf2f2c56Smiod           s = bfd_make_section (abfd,
1814*cf2f2c56Smiod                                 (bed->default_use_rela_p
1815*cf2f2c56Smiod                                  ? ".rela.bss" : ".rel.bss"));
1816*cf2f2c56Smiod           htab->srelbss = s;
1817*cf2f2c56Smiod           if (s == NULL
1818*cf2f2c56Smiod               || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
1819*cf2f2c56Smiod               || ! bfd_set_section_alignment (abfd, s, ptralign))
1820*cf2f2c56Smiod             return FALSE;
1821*cf2f2c56Smiod         }
1822*cf2f2c56Smiod     }
1823*cf2f2c56Smiod 
1824*cf2f2c56Smiod   return TRUE;
1825*cf2f2c56Smiod }
1826*cf2f2c56Smiod 
1827*cf2f2c56Smiod /* Copy the extra info we tack onto an elf_link_hash_entry.  */
1828*cf2f2c56Smiod static void m32r_elf_copy_indirect_symbol (const struct elf_backend_data *,
1829*cf2f2c56Smiod                                            struct elf_link_hash_entry *,
1830*cf2f2c56Smiod                                            struct elf_link_hash_entry *);
1831*cf2f2c56Smiod 
1832*cf2f2c56Smiod static void
m32r_elf_copy_indirect_symbol(const struct elf_backend_data * bed,struct elf_link_hash_entry * dir,struct elf_link_hash_entry * ind)1833*cf2f2c56Smiod m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
1834*cf2f2c56Smiod                                struct elf_link_hash_entry *dir,
1835*cf2f2c56Smiod                                struct elf_link_hash_entry *ind)
1836*cf2f2c56Smiod {
1837*cf2f2c56Smiod   struct elf_m32r_link_hash_entry *edir, *eind;
1838*cf2f2c56Smiod 
1839*cf2f2c56Smiod   edir = (struct elf_m32r_link_hash_entry *) dir;
1840*cf2f2c56Smiod   eind = (struct elf_m32r_link_hash_entry *) ind;
1841*cf2f2c56Smiod 
1842*cf2f2c56Smiod   if (eind->dyn_relocs != NULL)
1843*cf2f2c56Smiod     {
1844*cf2f2c56Smiod       if (edir->dyn_relocs != NULL)
1845*cf2f2c56Smiod         {
1846*cf2f2c56Smiod           struct elf_m32r_dyn_relocs **pp;
1847*cf2f2c56Smiod           struct elf_m32r_dyn_relocs *p;
1848*cf2f2c56Smiod 
1849*cf2f2c56Smiod           if (ind->root.type == bfd_link_hash_indirect)
1850*cf2f2c56Smiod             abort ();
1851*cf2f2c56Smiod 
1852*cf2f2c56Smiod           /* Add reloc counts against the weak sym to the strong sym
1853*cf2f2c56Smiod              list.  Merge any entries against the same section.  */
1854*cf2f2c56Smiod           for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
1855*cf2f2c56Smiod             {
1856*cf2f2c56Smiod               struct elf_m32r_dyn_relocs *q;
1857*cf2f2c56Smiod 
1858*cf2f2c56Smiod               for (q = edir->dyn_relocs; q != NULL; q = q->next)
1859*cf2f2c56Smiod                 if (q->sec == p->sec)
1860*cf2f2c56Smiod                   {
1861*cf2f2c56Smiod                     q->pc_count += p->pc_count;
1862*cf2f2c56Smiod                     q->count += p->count;
1863*cf2f2c56Smiod                     *pp = p->next;
1864*cf2f2c56Smiod                     break;
1865*cf2f2c56Smiod                   }
1866*cf2f2c56Smiod               if (q == NULL)
1867*cf2f2c56Smiod                 pp = &p->next;
1868*cf2f2c56Smiod             }
1869*cf2f2c56Smiod           *pp = edir->dyn_relocs;
1870*cf2f2c56Smiod         }
1871*cf2f2c56Smiod 
1872*cf2f2c56Smiod       edir->dyn_relocs = eind->dyn_relocs;
1873*cf2f2c56Smiod       eind->dyn_relocs = NULL;
1874*cf2f2c56Smiod     }
1875*cf2f2c56Smiod 
1876*cf2f2c56Smiod //  if (ind->root.type == bfd_link_hash_indirect
1877*cf2f2c56Smiod //      && dir->got.refcount <= 0)
1878*cf2f2c56Smiod //    {
1879*cf2f2c56Smiod //      edir->tls_type = eind->tls_type;
1880*cf2f2c56Smiod //      eind->tls_type = GOT_UNKNOWN;
1881*cf2f2c56Smiod //    }
1882*cf2f2c56Smiod   _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
1883*cf2f2c56Smiod }
1884*cf2f2c56Smiod 
1885*cf2f2c56Smiod 
1886*cf2f2c56Smiod /* Adjust a symbol defined by a dynamic object and referenced by a
1887*cf2f2c56Smiod    regular object.  The current definition is in some section of the
1888*cf2f2c56Smiod    dynamic object, but we're not including those sections.  We have to
1889*cf2f2c56Smiod    change the definition to something the rest of the link can
1890*cf2f2c56Smiod    understand.  */
1891*cf2f2c56Smiod 
1892*cf2f2c56Smiod static bfd_boolean
m32r_elf_adjust_dynamic_symbol(info,h)1893*cf2f2c56Smiod m32r_elf_adjust_dynamic_symbol (info, h)
1894*cf2f2c56Smiod      struct bfd_link_info *info;
1895*cf2f2c56Smiod      struct elf_link_hash_entry *h;
1896*cf2f2c56Smiod {
1897*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
1898*cf2f2c56Smiod   struct elf_m32r_link_hash_entry *eh;
1899*cf2f2c56Smiod   struct elf_m32r_dyn_relocs *p;
1900*cf2f2c56Smiod   bfd *dynobj;
1901*cf2f2c56Smiod   asection *s;
1902*cf2f2c56Smiod   unsigned int power_of_two;
1903*cf2f2c56Smiod 
1904*cf2f2c56Smiod #ifdef DEBUG_PIC
1905*cf2f2c56Smiod printf("m32r_elf_adjust_dynamic_symbol()\n");
1906*cf2f2c56Smiod #endif
1907*cf2f2c56Smiod 
1908*cf2f2c56Smiod   dynobj = elf_hash_table (info)->dynobj;
1909*cf2f2c56Smiod 
1910*cf2f2c56Smiod   /* Make sure we know what is going on here.  */
1911*cf2f2c56Smiod   BFD_ASSERT (dynobj != NULL
1912*cf2f2c56Smiod               && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
1913*cf2f2c56Smiod                   || h->weakdef != NULL
1914*cf2f2c56Smiod                   || ((h->elf_link_hash_flags
1915*cf2f2c56Smiod                        & ELF_LINK_HASH_DEF_DYNAMIC) != 0
1916*cf2f2c56Smiod                       && (h->elf_link_hash_flags
1917*cf2f2c56Smiod                           & ELF_LINK_HASH_REF_REGULAR) != 0
1918*cf2f2c56Smiod                       && (h->elf_link_hash_flags
1919*cf2f2c56Smiod                           & ELF_LINK_HASH_DEF_REGULAR) == 0)));
1920*cf2f2c56Smiod 
1921*cf2f2c56Smiod 
1922*cf2f2c56Smiod   /* If this is a function, put it in the procedure linkage table.  We
1923*cf2f2c56Smiod      will fill in the contents of the procedure linkage table later,
1924*cf2f2c56Smiod      when we know the address of the .got section.  */
1925*cf2f2c56Smiod   if (h->type == STT_FUNC
1926*cf2f2c56Smiod       || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
1927*cf2f2c56Smiod     {
1928*cf2f2c56Smiod       if (! info->shared
1929*cf2f2c56Smiod           && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
1930*cf2f2c56Smiod           && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
1931*cf2f2c56Smiod 	  && h->root.type != bfd_link_hash_undefweak
1932*cf2f2c56Smiod 	  && h->root.type != bfd_link_hash_undefined)
1933*cf2f2c56Smiod         {
1934*cf2f2c56Smiod           /* This case can occur if we saw a PLT reloc in an input
1935*cf2f2c56Smiod              file, but the symbol was never referred to by a dynamic
1936*cf2f2c56Smiod              object.  In such a case, we don't actually need to build
1937*cf2f2c56Smiod              a procedure linkage table, and we can just do a PCREL
1938*cf2f2c56Smiod              reloc instead.  */
1939*cf2f2c56Smiod           h->plt.offset = (bfd_vma) -1;
1940*cf2f2c56Smiod           h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1941*cf2f2c56Smiod         }
1942*cf2f2c56Smiod 
1943*cf2f2c56Smiod       return TRUE;
1944*cf2f2c56Smiod     }
1945*cf2f2c56Smiod   else
1946*cf2f2c56Smiod     h->plt.offset = (bfd_vma) -1;
1947*cf2f2c56Smiod 
1948*cf2f2c56Smiod   /* If this is a weak symbol, and there is a real definition, the
1949*cf2f2c56Smiod      processor independent code will have arranged for us to see the
1950*cf2f2c56Smiod      real definition first, and we can just use the same value.  */
1951*cf2f2c56Smiod   if (h->weakdef != NULL)
1952*cf2f2c56Smiod     {
1953*cf2f2c56Smiod       BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
1954*cf2f2c56Smiod                   || h->weakdef->root.type == bfd_link_hash_defweak);
1955*cf2f2c56Smiod       h->root.u.def.section = h->weakdef->root.u.def.section;
1956*cf2f2c56Smiod       h->root.u.def.value = h->weakdef->root.u.def.value;
1957*cf2f2c56Smiod       return TRUE;
1958*cf2f2c56Smiod     }
1959*cf2f2c56Smiod 
1960*cf2f2c56Smiod   /* This is a reference to a symbol defined by a dynamic object which
1961*cf2f2c56Smiod      is not a function.  */
1962*cf2f2c56Smiod 
1963*cf2f2c56Smiod   /* If we are creating a shared library, we must presume that the
1964*cf2f2c56Smiod      only references to the symbol are via the global offset table.
1965*cf2f2c56Smiod      For such cases we need not do anything here; the relocations will
1966*cf2f2c56Smiod      be handled correctly by relocate_section.  */
1967*cf2f2c56Smiod   if (info->shared)
1968*cf2f2c56Smiod     return TRUE;
1969*cf2f2c56Smiod 
1970*cf2f2c56Smiod   /* If there are no references to this symbol that do not use the
1971*cf2f2c56Smiod      GOT, we don't need to generate a copy reloc.  */
1972*cf2f2c56Smiod   if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
1973*cf2f2c56Smiod     return TRUE;
1974*cf2f2c56Smiod 
1975*cf2f2c56Smiod   /* If -z nocopyreloc was given, we won't generate them either.  */
1976*cf2f2c56Smiod   if (info->nocopyreloc)
1977*cf2f2c56Smiod     {
1978*cf2f2c56Smiod       h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
1979*cf2f2c56Smiod       return TRUE;
1980*cf2f2c56Smiod     }
1981*cf2f2c56Smiod 
1982*cf2f2c56Smiod   eh = (struct elf_m32r_link_hash_entry *) h;
1983*cf2f2c56Smiod   for (p = eh->dyn_relocs; p != NULL; p = p->next)
1984*cf2f2c56Smiod     {
1985*cf2f2c56Smiod       s = p->sec->output_section;
1986*cf2f2c56Smiod       if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
1987*cf2f2c56Smiod         break;
1988*cf2f2c56Smiod     }
1989*cf2f2c56Smiod 
1990*cf2f2c56Smiod   /* If we didn't find any dynamic relocs in sections which needs the
1991*cf2f2c56Smiod      copy reloc, then we'll be keeping the dynamic relocs and avoiding
1992*cf2f2c56Smiod      the copy reloc.  */
1993*cf2f2c56Smiod   if (p == NULL)
1994*cf2f2c56Smiod     {
1995*cf2f2c56Smiod       h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
1996*cf2f2c56Smiod       return TRUE;
1997*cf2f2c56Smiod     }
1998*cf2f2c56Smiod 
1999*cf2f2c56Smiod   /* We must allocate the symbol in our .dynbss section, which will
2000*cf2f2c56Smiod      become part of the .bss section of the executable.  There will be
2001*cf2f2c56Smiod      an entry for this symbol in the .dynsym section.  The dynamic
2002*cf2f2c56Smiod      object will contain position independent code, so all references
2003*cf2f2c56Smiod      from the dynamic object to this symbol will go through the global
2004*cf2f2c56Smiod      offset table.  The dynamic linker will use the .dynsym entry to
2005*cf2f2c56Smiod      determine the address it must put in the global offset table, so
2006*cf2f2c56Smiod      both the dynamic object and the regular object will refer to the
2007*cf2f2c56Smiod      same memory location for the variable.  */
2008*cf2f2c56Smiod 
2009*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
2010*cf2f2c56Smiod   s = htab->sdynbss;
2011*cf2f2c56Smiod   BFD_ASSERT (s != NULL);
2012*cf2f2c56Smiod 
2013*cf2f2c56Smiod   /* We must generate a R_M32R_COPY reloc to tell the dynamic linker
2014*cf2f2c56Smiod      to copy the initial value out of the dynamic object and into the
2015*cf2f2c56Smiod      runtime process image.  We need to remember the offset into the
2016*cf2f2c56Smiod      .rela.bss section we are going to use.  */
2017*cf2f2c56Smiod   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2018*cf2f2c56Smiod     {
2019*cf2f2c56Smiod       asection *srel;
2020*cf2f2c56Smiod 
2021*cf2f2c56Smiod       srel = htab->srelbss;
2022*cf2f2c56Smiod       BFD_ASSERT (srel != NULL);
2023*cf2f2c56Smiod       srel->_raw_size += sizeof (Elf32_External_Rela);
2024*cf2f2c56Smiod       h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
2025*cf2f2c56Smiod     }
2026*cf2f2c56Smiod 
2027*cf2f2c56Smiod   /* We need to figure out the alignment required for this symbol.  I
2028*cf2f2c56Smiod      have no idea how ELF linkers handle this.  */
2029*cf2f2c56Smiod   power_of_two = bfd_log2 (h->size);
2030*cf2f2c56Smiod   if (power_of_two > 3)
2031*cf2f2c56Smiod     power_of_two = 3;
2032*cf2f2c56Smiod 
2033*cf2f2c56Smiod   /* Apply the required alignment.  */
2034*cf2f2c56Smiod   s->_raw_size = BFD_ALIGN (s->_raw_size,
2035*cf2f2c56Smiod                             (bfd_size_type) (1 << power_of_two));
2036*cf2f2c56Smiod   if (power_of_two > bfd_get_section_alignment (dynobj, s))
2037*cf2f2c56Smiod     {
2038*cf2f2c56Smiod       if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2039*cf2f2c56Smiod         return FALSE;
2040*cf2f2c56Smiod     }
2041*cf2f2c56Smiod 
2042*cf2f2c56Smiod   /* Define the symbol as being at this point in the section.  */
2043*cf2f2c56Smiod   h->root.u.def.section = s;
2044*cf2f2c56Smiod   h->root.u.def.value = s->_raw_size;
2045*cf2f2c56Smiod 
2046*cf2f2c56Smiod   /* Increment the section size to make room for the symbol.  */
2047*cf2f2c56Smiod   s->_raw_size += h->size;
2048*cf2f2c56Smiod 
2049*cf2f2c56Smiod   return TRUE;
2050*cf2f2c56Smiod }
2051*cf2f2c56Smiod 
2052*cf2f2c56Smiod /* Allocate space in .plt, .got and associated reloc sections for
2053*cf2f2c56Smiod    dynamic relocs.  */
2054*cf2f2c56Smiod 
2055*cf2f2c56Smiod static bfd_boolean
allocate_dynrelocs(h,inf)2056*cf2f2c56Smiod allocate_dynrelocs (h, inf)
2057*cf2f2c56Smiod      struct elf_link_hash_entry *h;
2058*cf2f2c56Smiod      PTR inf;
2059*cf2f2c56Smiod {
2060*cf2f2c56Smiod   struct bfd_link_info *info;
2061*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
2062*cf2f2c56Smiod   struct elf_m32r_link_hash_entry *eh;
2063*cf2f2c56Smiod   struct elf_m32r_dyn_relocs *p;
2064*cf2f2c56Smiod 
2065*cf2f2c56Smiod   if (h->root.type == bfd_link_hash_indirect)
2066*cf2f2c56Smiod     return TRUE;
2067*cf2f2c56Smiod 
2068*cf2f2c56Smiod   if (h->root.type == bfd_link_hash_warning)
2069*cf2f2c56Smiod     /* When warning symbols are created, they **replace** the "real"
2070*cf2f2c56Smiod        entry in the hash table, thus we never get to see the real
2071*cf2f2c56Smiod        symbol in a hash traversal.  So look at it now.  */
2072*cf2f2c56Smiod     h = (struct elf_link_hash_entry *) h->root.u.i.link;
2073*cf2f2c56Smiod 
2074*cf2f2c56Smiod   info = (struct bfd_link_info *) inf;
2075*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
2076*cf2f2c56Smiod 
2077*cf2f2c56Smiod   eh = (struct elf_m32r_link_hash_entry *) h;
2078*cf2f2c56Smiod //  if ((h->got.refcount > 0
2079*cf2f2c56Smiod //      || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
2080*cf2f2c56Smiod //      && eh->gotplt_refcount > 0)
2081*cf2f2c56Smiod //    {
2082*cf2f2c56Smiod //      /* The symbol has been forced local, or we have some direct got refs,
2083*cf2f2c56Smiod //         so treat all the gotplt refs as got refs. */
2084*cf2f2c56Smiod //      h->got.refcount += eh->gotplt_refcount;
2085*cf2f2c56Smiod //      if (h->plt.refcount >= eh->gotplt_refcount)
2086*cf2f2c56Smiod //        h->plt.refcount -= eh->gotplt_refcount;
2087*cf2f2c56Smiod //    }
2088*cf2f2c56Smiod 
2089*cf2f2c56Smiod   if (htab->root.dynamic_sections_created
2090*cf2f2c56Smiod       && h->plt.refcount > 0)
2091*cf2f2c56Smiod     {
2092*cf2f2c56Smiod       /* Make sure this symbol is output as a dynamic symbol.
2093*cf2f2c56Smiod          Undefined weak syms won't yet be marked as dynamic.  */
2094*cf2f2c56Smiod       if (h->dynindx == -1
2095*cf2f2c56Smiod           && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
2096*cf2f2c56Smiod         {
2097*cf2f2c56Smiod           if (! bfd_elf_link_record_dynamic_symbol (info, h))
2098*cf2f2c56Smiod             return FALSE;
2099*cf2f2c56Smiod         }
2100*cf2f2c56Smiod 
2101*cf2f2c56Smiod       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
2102*cf2f2c56Smiod         {
2103*cf2f2c56Smiod           asection *s = htab->splt;
2104*cf2f2c56Smiod 
2105*cf2f2c56Smiod           /* If this is the first .plt entry, make room for the special
2106*cf2f2c56Smiod              first entry.  */
2107*cf2f2c56Smiod           if (s->_raw_size == 0)
2108*cf2f2c56Smiod             s->_raw_size += PLT_ENTRY_SIZE;
2109*cf2f2c56Smiod 
2110*cf2f2c56Smiod           h->plt.offset = s->_raw_size;
2111*cf2f2c56Smiod 
2112*cf2f2c56Smiod           /* If this symbol is not defined in a regular file, and we are
2113*cf2f2c56Smiod              not generating a shared library, then set the symbol to this
2114*cf2f2c56Smiod              location in the .plt.  This is required to make function
2115*cf2f2c56Smiod              pointers compare as equal between the normal executable and
2116*cf2f2c56Smiod              the shared library.  */
2117*cf2f2c56Smiod           if (! info->shared
2118*cf2f2c56Smiod               && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
2119*cf2f2c56Smiod             {
2120*cf2f2c56Smiod               h->root.u.def.section = s;
2121*cf2f2c56Smiod               h->root.u.def.value = h->plt.offset;
2122*cf2f2c56Smiod             }
2123*cf2f2c56Smiod 
2124*cf2f2c56Smiod           /* Make room for this entry.  */
2125*cf2f2c56Smiod           s->_raw_size += PLT_ENTRY_SIZE;
2126*cf2f2c56Smiod 
2127*cf2f2c56Smiod           /* We also need to make an entry in the .got.plt section, which
2128*cf2f2c56Smiod              will be placed in the .got section by the linker script.  */
2129*cf2f2c56Smiod           htab->sgotplt->_raw_size += 4;
2130*cf2f2c56Smiod 
2131*cf2f2c56Smiod           /* We also need to make an entry in the .rel.plt section.  */
2132*cf2f2c56Smiod           htab->srelplt->_raw_size += sizeof (Elf32_External_Rela);
2133*cf2f2c56Smiod         }
2134*cf2f2c56Smiod       else
2135*cf2f2c56Smiod         {
2136*cf2f2c56Smiod           h->plt.offset = (bfd_vma) -1;
2137*cf2f2c56Smiod           h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
2138*cf2f2c56Smiod         }
2139*cf2f2c56Smiod     }
2140*cf2f2c56Smiod   else
2141*cf2f2c56Smiod     {
2142*cf2f2c56Smiod       h->plt.offset = (bfd_vma) -1;
2143*cf2f2c56Smiod       h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
2144*cf2f2c56Smiod     }
2145*cf2f2c56Smiod 
2146*cf2f2c56Smiod   if (h->got.refcount > 0)
2147*cf2f2c56Smiod     {
2148*cf2f2c56Smiod       asection *s;
2149*cf2f2c56Smiod       bfd_boolean dyn;
2150*cf2f2c56Smiod 
2151*cf2f2c56Smiod       /* Make sure this symbol is output as a dynamic symbol.
2152*cf2f2c56Smiod          Undefined weak syms won't yet be marked as dynamic.  */
2153*cf2f2c56Smiod       if (h->dynindx == -1
2154*cf2f2c56Smiod           && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
2155*cf2f2c56Smiod         {
2156*cf2f2c56Smiod           if (! bfd_elf_link_record_dynamic_symbol (info, h))
2157*cf2f2c56Smiod             return FALSE;
2158*cf2f2c56Smiod         }
2159*cf2f2c56Smiod 
2160*cf2f2c56Smiod       s = htab->sgot;
2161*cf2f2c56Smiod 
2162*cf2f2c56Smiod       h->got.offset = s->_raw_size;
2163*cf2f2c56Smiod       s->_raw_size += 4;
2164*cf2f2c56Smiod       dyn = htab->root.dynamic_sections_created;
2165*cf2f2c56Smiod       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
2166*cf2f2c56Smiod         htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
2167*cf2f2c56Smiod     }
2168*cf2f2c56Smiod   else
2169*cf2f2c56Smiod     h->got.offset = (bfd_vma) -1;
2170*cf2f2c56Smiod 
2171*cf2f2c56Smiod   if (eh->dyn_relocs == NULL)
2172*cf2f2c56Smiod     return TRUE;
2173*cf2f2c56Smiod 
2174*cf2f2c56Smiod   /* In the shared -Bsymbolic case, discard space allocated for
2175*cf2f2c56Smiod      dynamic pc-relative relocs against symbols which turn out to be
2176*cf2f2c56Smiod      defined in regular objects.  For the normal shared case, discard
2177*cf2f2c56Smiod      space for pc-relative relocs that have become local due to symbol
2178*cf2f2c56Smiod      visibility changes.  */
2179*cf2f2c56Smiod 
2180*cf2f2c56Smiod   if (info->shared)
2181*cf2f2c56Smiod     {
2182*cf2f2c56Smiod       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
2183*cf2f2c56Smiod           && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
2184*cf2f2c56Smiod               || info->symbolic))
2185*cf2f2c56Smiod         {
2186*cf2f2c56Smiod           struct elf_m32r_dyn_relocs **pp;
2187*cf2f2c56Smiod           for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2188*cf2f2c56Smiod             {
2189*cf2f2c56Smiod               p->count -= p->pc_count;
2190*cf2f2c56Smiod               p->pc_count = 0;
2191*cf2f2c56Smiod               if (p->count == 0)
2192*cf2f2c56Smiod                 *pp = p->next;
2193*cf2f2c56Smiod               else
2194*cf2f2c56Smiod                 pp = &p->next;
2195*cf2f2c56Smiod             }
2196*cf2f2c56Smiod         }
2197*cf2f2c56Smiod     }
2198*cf2f2c56Smiod   else
2199*cf2f2c56Smiod     {
2200*cf2f2c56Smiod       /* For the non-shared case, discard space for relocs against
2201*cf2f2c56Smiod          symbols which turn out to need copy relocs or are not
2202*cf2f2c56Smiod          dynamic.  */
2203*cf2f2c56Smiod 
2204*cf2f2c56Smiod       if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
2205*cf2f2c56Smiod           && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
2206*cf2f2c56Smiod                && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
2207*cf2f2c56Smiod               || (htab->root.dynamic_sections_created
2208*cf2f2c56Smiod                   && (h->root.type == bfd_link_hash_undefweak
2209*cf2f2c56Smiod                       || h->root.type == bfd_link_hash_undefined))))
2210*cf2f2c56Smiod         {
2211*cf2f2c56Smiod           /* Make sure this symbol is output as a dynamic symbol.
2212*cf2f2c56Smiod              Undefined weak syms won't yet be marked as dynamic.  */
2213*cf2f2c56Smiod           if (h->dynindx == -1
2214*cf2f2c56Smiod               && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
2215*cf2f2c56Smiod             {
2216*cf2f2c56Smiod               if (! bfd_elf_link_record_dynamic_symbol (info, h))
2217*cf2f2c56Smiod                 return FALSE;
2218*cf2f2c56Smiod             }
2219*cf2f2c56Smiod 
2220*cf2f2c56Smiod           /* If that succeeded, we know we'll be keeping all the
2221*cf2f2c56Smiod              relocs.  */
2222*cf2f2c56Smiod           if (h->dynindx != -1)
2223*cf2f2c56Smiod             goto keep;
2224*cf2f2c56Smiod         }
2225*cf2f2c56Smiod 
2226*cf2f2c56Smiod       eh->dyn_relocs = NULL;
2227*cf2f2c56Smiod 
2228*cf2f2c56Smiod     keep: ;
2229*cf2f2c56Smiod     }
2230*cf2f2c56Smiod 
2231*cf2f2c56Smiod   /* Finally, allocate space.  */
2232*cf2f2c56Smiod   for (p = eh->dyn_relocs; p != NULL; p = p->next)
2233*cf2f2c56Smiod     {
2234*cf2f2c56Smiod       asection *sreloc = elf_section_data (p->sec)->sreloc;
2235*cf2f2c56Smiod       sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela);
2236*cf2f2c56Smiod     }
2237*cf2f2c56Smiod 
2238*cf2f2c56Smiod   return TRUE;
2239*cf2f2c56Smiod }
2240*cf2f2c56Smiod /* Find any dynamic relocs that apply to read-only sections.  */
2241*cf2f2c56Smiod 
2242*cf2f2c56Smiod static bfd_boolean
readonly_dynrelocs(h,inf)2243*cf2f2c56Smiod readonly_dynrelocs (h, inf)
2244*cf2f2c56Smiod      struct elf_link_hash_entry *h;
2245*cf2f2c56Smiod      PTR inf;
2246*cf2f2c56Smiod {
2247*cf2f2c56Smiod   struct elf_m32r_link_hash_entry *eh;
2248*cf2f2c56Smiod   struct elf_m32r_dyn_relocs *p;
2249*cf2f2c56Smiod 
2250*cf2f2c56Smiod   if (h->root.type == bfd_link_hash_warning)
2251*cf2f2c56Smiod     h = (struct elf_link_hash_entry *) h->root.u.i.link;
2252*cf2f2c56Smiod 
2253*cf2f2c56Smiod   eh = (struct elf_m32r_link_hash_entry *) h;
2254*cf2f2c56Smiod   for (p = eh->dyn_relocs; p != NULL; p = p->next)
2255*cf2f2c56Smiod     {
2256*cf2f2c56Smiod       asection *s = p->sec->output_section;
2257*cf2f2c56Smiod 
2258*cf2f2c56Smiod       if (s != NULL && (s->flags & SEC_READONLY) != 0)
2259*cf2f2c56Smiod         {
2260*cf2f2c56Smiod           struct bfd_link_info *info = (struct bfd_link_info *) inf;
2261*cf2f2c56Smiod 
2262*cf2f2c56Smiod           info->flags |= DF_TEXTREL;
2263*cf2f2c56Smiod 
2264*cf2f2c56Smiod           /* Not an error, just cut short the traversal.  */
2265*cf2f2c56Smiod           return FALSE;
2266*cf2f2c56Smiod         }
2267*cf2f2c56Smiod     }
2268*cf2f2c56Smiod   return TRUE;
2269*cf2f2c56Smiod }
2270*cf2f2c56Smiod 
2271*cf2f2c56Smiod /* Set the sizes of the dynamic sections.  */
2272*cf2f2c56Smiod 
2273*cf2f2c56Smiod static bfd_boolean
m32r_elf_size_dynamic_sections(output_bfd,info)2274*cf2f2c56Smiod m32r_elf_size_dynamic_sections (output_bfd, info)
2275*cf2f2c56Smiod      bfd *output_bfd ATTRIBUTE_UNUSED;
2276*cf2f2c56Smiod      struct bfd_link_info *info;
2277*cf2f2c56Smiod {
2278*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
2279*cf2f2c56Smiod   bfd *dynobj;
2280*cf2f2c56Smiod   asection *s;
2281*cf2f2c56Smiod   bfd_boolean relocs;
2282*cf2f2c56Smiod   bfd *ibfd;
2283*cf2f2c56Smiod 
2284*cf2f2c56Smiod #ifdef DEBUG_PIC
2285*cf2f2c56Smiod printf("m32r_elf_size_dynamic_sections()\n");
2286*cf2f2c56Smiod #endif
2287*cf2f2c56Smiod 
2288*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
2289*cf2f2c56Smiod   dynobj = htab->root.dynobj;
2290*cf2f2c56Smiod   BFD_ASSERT (dynobj != NULL);
2291*cf2f2c56Smiod 
2292*cf2f2c56Smiod   if (htab->root.dynamic_sections_created)
2293*cf2f2c56Smiod     {
2294*cf2f2c56Smiod       /* Set the contents of the .interp section to the interpreter.  */
2295*cf2f2c56Smiod       if (! info->shared)
2296*cf2f2c56Smiod 	{
2297*cf2f2c56Smiod 	  s = bfd_get_section_by_name (dynobj, ".interp");
2298*cf2f2c56Smiod 	  BFD_ASSERT (s != NULL);
2299*cf2f2c56Smiod 	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
2300*cf2f2c56Smiod 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2301*cf2f2c56Smiod 	}
2302*cf2f2c56Smiod     }
2303*cf2f2c56Smiod 
2304*cf2f2c56Smiod   /* Set up .got offsets for local syms, and space for local dynamic
2305*cf2f2c56Smiod      relocs.  */
2306*cf2f2c56Smiod   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2307*cf2f2c56Smiod     {
2308*cf2f2c56Smiod       bfd_signed_vma *local_got;
2309*cf2f2c56Smiod       bfd_signed_vma *end_local_got;
2310*cf2f2c56Smiod       bfd_size_type locsymcount;
2311*cf2f2c56Smiod       Elf_Internal_Shdr *symtab_hdr;
2312*cf2f2c56Smiod       asection *srel;
2313*cf2f2c56Smiod 
2314*cf2f2c56Smiod       if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2315*cf2f2c56Smiod         continue;
2316*cf2f2c56Smiod 
2317*cf2f2c56Smiod       for (s = ibfd->sections; s != NULL; s = s->next)
2318*cf2f2c56Smiod         {
2319*cf2f2c56Smiod           struct elf_m32r_dyn_relocs *p;
2320*cf2f2c56Smiod 
2321*cf2f2c56Smiod           for (p = ((struct elf_m32r_dyn_relocs *)
2322*cf2f2c56Smiod                     elf_section_data (s)->local_dynrel);
2323*cf2f2c56Smiod                p != NULL;
2324*cf2f2c56Smiod                p = p->next)
2325*cf2f2c56Smiod             {
2326*cf2f2c56Smiod               if (! bfd_is_abs_section (p->sec)
2327*cf2f2c56Smiod                   && bfd_is_abs_section (p->sec->output_section))
2328*cf2f2c56Smiod                 {
2329*cf2f2c56Smiod                   /* Input section has been discarded, either because
2330*cf2f2c56Smiod                      it is a copy of a linkonce section or due to
2331*cf2f2c56Smiod                      linker script /DISCARD/, so we'll be discarding
2332*cf2f2c56Smiod                      the relocs too.  */
2333*cf2f2c56Smiod                 }
2334*cf2f2c56Smiod               else if (p->count != 0)
2335*cf2f2c56Smiod                 {
2336*cf2f2c56Smiod                   srel = elf_section_data (p->sec)->sreloc;
2337*cf2f2c56Smiod                   srel->_raw_size += p->count * sizeof (Elf32_External_Rela);
2338*cf2f2c56Smiod                   if ((p->sec->output_section->flags & SEC_READONLY) != 0)
2339*cf2f2c56Smiod                     info->flags |= DF_TEXTREL;
2340*cf2f2c56Smiod                 }
2341*cf2f2c56Smiod             }
2342*cf2f2c56Smiod         }
2343*cf2f2c56Smiod 
2344*cf2f2c56Smiod       local_got = elf_local_got_refcounts (ibfd);
2345*cf2f2c56Smiod       if (!local_got)
2346*cf2f2c56Smiod         continue;
2347*cf2f2c56Smiod 
2348*cf2f2c56Smiod       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2349*cf2f2c56Smiod       locsymcount = symtab_hdr->sh_info;
2350*cf2f2c56Smiod       end_local_got = local_got + locsymcount;
2351*cf2f2c56Smiod       s = htab->sgot;
2352*cf2f2c56Smiod       srel = htab->srelgot;
2353*cf2f2c56Smiod       for (; local_got < end_local_got; ++local_got)
2354*cf2f2c56Smiod         {
2355*cf2f2c56Smiod           if (*local_got > 0)
2356*cf2f2c56Smiod             {
2357*cf2f2c56Smiod               *local_got = s->_raw_size;
2358*cf2f2c56Smiod               s->_raw_size += 4;
2359*cf2f2c56Smiod               if (info->shared)
2360*cf2f2c56Smiod                 srel->_raw_size += sizeof (Elf32_External_Rela);
2361*cf2f2c56Smiod             }
2362*cf2f2c56Smiod           else
2363*cf2f2c56Smiod             *local_got = (bfd_vma) -1;
2364*cf2f2c56Smiod         }
2365*cf2f2c56Smiod     }
2366*cf2f2c56Smiod 
2367*cf2f2c56Smiod   /* Allocate global sym .plt and .got entries, and space for global
2368*cf2f2c56Smiod      sym dynamic relocs.  */
2369*cf2f2c56Smiod   elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info);
2370*cf2f2c56Smiod 
2371*cf2f2c56Smiod   /* We now have determined the sizes of the various dynamic sections.
2372*cf2f2c56Smiod      Allocate memory for them.  */
2373*cf2f2c56Smiod   relocs = FALSE;
2374*cf2f2c56Smiod   for (s = dynobj->sections; s != NULL; s = s->next)
2375*cf2f2c56Smiod     {
2376*cf2f2c56Smiod       if ((s->flags & SEC_LINKER_CREATED) == 0)
2377*cf2f2c56Smiod         continue;
2378*cf2f2c56Smiod 
2379*cf2f2c56Smiod       if (s == htab->splt
2380*cf2f2c56Smiod           || s == htab->sgot
2381*cf2f2c56Smiod           || s == htab->sgotplt)
2382*cf2f2c56Smiod         {
2383*cf2f2c56Smiod           /* Strip this section if we don't need it; see the
2384*cf2f2c56Smiod              comment below.  */
2385*cf2f2c56Smiod         }
2386*cf2f2c56Smiod       else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
2387*cf2f2c56Smiod         {
2388*cf2f2c56Smiod           if (s->_raw_size != 0 && s != htab->srelplt)
2389*cf2f2c56Smiod             relocs = TRUE;
2390*cf2f2c56Smiod 
2391*cf2f2c56Smiod           /* We use the reloc_count field as a counter if we need
2392*cf2f2c56Smiod              to copy relocs into the output file.  */
2393*cf2f2c56Smiod           s->reloc_count = 0;
2394*cf2f2c56Smiod         }
2395*cf2f2c56Smiod       else
2396*cf2f2c56Smiod         {
2397*cf2f2c56Smiod           /* It's not one of our sections, so don't allocate space.  */
2398*cf2f2c56Smiod           continue;
2399*cf2f2c56Smiod         }
2400*cf2f2c56Smiod 
2401*cf2f2c56Smiod       if (s->_raw_size == 0)
2402*cf2f2c56Smiod         {
2403*cf2f2c56Smiod           /* If we don't need this section, strip it from the
2404*cf2f2c56Smiod              output file.  This is mostly to handle .rela.bss and
2405*cf2f2c56Smiod              .rela.plt.  We must create both sections in
2406*cf2f2c56Smiod              create_dynamic_sections, because they must be created
2407*cf2f2c56Smiod              before the linker maps input sections to output
2408*cf2f2c56Smiod              sections.  The linker does that before
2409*cf2f2c56Smiod              adjust_dynamic_symbol is called, and it is that
2410*cf2f2c56Smiod              function which decides whether anything needs to go
2411*cf2f2c56Smiod              into these sections.  */
2412*cf2f2c56Smiod           _bfd_strip_section_from_output (info, s);
2413*cf2f2c56Smiod           continue;
2414*cf2f2c56Smiod         }
2415*cf2f2c56Smiod 
2416*cf2f2c56Smiod       /* Allocate memory for the section contents.  We use bfd_zalloc
2417*cf2f2c56Smiod          here in case unused entries are not reclaimed before the
2418*cf2f2c56Smiod          section's contents are written out.  This should not happen,
2419*cf2f2c56Smiod          but this way if it does, we get a R_M32R_NONE reloc instead
2420*cf2f2c56Smiod          of garbage.  */
2421*cf2f2c56Smiod       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
2422*cf2f2c56Smiod       if (s->contents == NULL)
2423*cf2f2c56Smiod         return FALSE;
2424*cf2f2c56Smiod     }
2425*cf2f2c56Smiod 
2426*cf2f2c56Smiod   if (htab->root.dynamic_sections_created)
2427*cf2f2c56Smiod     {
2428*cf2f2c56Smiod       /* Add some entries to the .dynamic section.  We fill in the
2429*cf2f2c56Smiod 	 values later, in m32r_elf_finish_dynamic_sections, but we
2430*cf2f2c56Smiod 	 must add the entries now so that we get the correct size for
2431*cf2f2c56Smiod 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
2432*cf2f2c56Smiod 	 dynamic linker and used by the debugger.  */
2433*cf2f2c56Smiod #define add_dynamic_entry(TAG, VAL) \
2434*cf2f2c56Smiod   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2435*cf2f2c56Smiod 
2436*cf2f2c56Smiod       if (! info->shared)
2437*cf2f2c56Smiod 	{
2438*cf2f2c56Smiod 	  if (! add_dynamic_entry (DT_DEBUG, 0))
2439*cf2f2c56Smiod 	    return FALSE;
2440*cf2f2c56Smiod 	}
2441*cf2f2c56Smiod 
2442*cf2f2c56Smiod       if (htab->splt->_raw_size != 0)
2443*cf2f2c56Smiod         {
2444*cf2f2c56Smiod           if (! add_dynamic_entry (DT_PLTGOT, 0)
2445*cf2f2c56Smiod               || ! add_dynamic_entry (DT_PLTRELSZ, 0)
2446*cf2f2c56Smiod               || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
2447*cf2f2c56Smiod               || ! add_dynamic_entry (DT_JMPREL, 0))
2448*cf2f2c56Smiod             return FALSE;
2449*cf2f2c56Smiod         }
2450*cf2f2c56Smiod 
2451*cf2f2c56Smiod       if (relocs)
2452*cf2f2c56Smiod         {
2453*cf2f2c56Smiod           if (! add_dynamic_entry (DT_RELA, 0)
2454*cf2f2c56Smiod               || ! add_dynamic_entry (DT_RELASZ, 0)
2455*cf2f2c56Smiod               || ! add_dynamic_entry (DT_RELAENT,
2456*cf2f2c56Smiod                                       sizeof (Elf32_External_Rela)))
2457*cf2f2c56Smiod             return FALSE;
2458*cf2f2c56Smiod 
2459*cf2f2c56Smiod           /* If any dynamic relocs apply to a read-only section,
2460*cf2f2c56Smiod              then we need a DT_TEXTREL entry.  */
2461*cf2f2c56Smiod           if ((info->flags & DF_TEXTREL) == 0)
2462*cf2f2c56Smiod             elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
2463*cf2f2c56Smiod                                     (PTR) info);
2464*cf2f2c56Smiod 
2465*cf2f2c56Smiod           if ((info->flags & DF_TEXTREL) != 0)
2466*cf2f2c56Smiod             {
2467*cf2f2c56Smiod               if (! add_dynamic_entry (DT_TEXTREL, 0))
2468*cf2f2c56Smiod                 return FALSE;
2469*cf2f2c56Smiod             }
2470*cf2f2c56Smiod         }
2471*cf2f2c56Smiod     }
2472*cf2f2c56Smiod #undef add_dynamic_entry
2473*cf2f2c56Smiod 
2474*cf2f2c56Smiod   return TRUE;
2475*cf2f2c56Smiod }
2476fddef416Sniklas /* Relocate an M32R/D ELF section.
2477fddef416Sniklas    There is some attempt to make this function usable for many architectures,
2478d2201f2fSdrahn    both for RELA and REL type relocs, if only to serve as a learning tool.
2479fddef416Sniklas 
2480fddef416Sniklas    The RELOCATE_SECTION function is called by the new ELF backend linker
2481fddef416Sniklas    to handle the relocations for a section.
2482fddef416Sniklas 
2483fddef416Sniklas    The relocs are always passed as Rela structures; if the section
2484fddef416Sniklas    actually uses Rel structures, the r_addend field will always be
2485fddef416Sniklas    zero.
2486fddef416Sniklas 
2487fddef416Sniklas    This function is responsible for adjust the section contents as
2488fddef416Sniklas    necessary, and (if using Rela relocs and generating a
2489*cf2f2c56Smiod    relocatable output file) adjusting the reloc addend as
2490fddef416Sniklas    necessary.
2491fddef416Sniklas 
2492fddef416Sniklas    This function does not have to worry about setting the reloc
2493fddef416Sniklas    address or the reloc symbol index.
2494fddef416Sniklas 
2495fddef416Sniklas    LOCAL_SYMS is a pointer to the swapped in local symbols.
2496fddef416Sniklas 
2497fddef416Sniklas    LOCAL_SECTIONS is an array giving the section in the input file
2498fddef416Sniklas    corresponding to the st_shndx field of each local symbol.
2499fddef416Sniklas 
2500fddef416Sniklas    The global hash table entry for the global symbols can be found
2501fddef416Sniklas    via elf_sym_hashes (input_bfd).
2502fddef416Sniklas 
2503*cf2f2c56Smiod    When generating relocatable output, this function must handle
2504fddef416Sniklas    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
2505fddef416Sniklas    going to be the section symbol corresponding to the output
2506fddef416Sniklas    section, which means that the addend must be adjusted
2507fddef416Sniklas    accordingly.  */
2508fddef416Sniklas 
2509d2201f2fSdrahn static bfd_boolean
m32r_elf_relocate_section(output_bfd,info,input_bfd,input_section,contents,relocs,local_syms,local_sections)2510fddef416Sniklas m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
2511fddef416Sniklas 			   contents, relocs, local_syms, local_sections)
2512f7cc78ecSespie      bfd *output_bfd ATTRIBUTE_UNUSED;
2513fddef416Sniklas      struct bfd_link_info *info;
2514fddef416Sniklas      bfd *input_bfd;
2515fddef416Sniklas      asection *input_section;
2516fddef416Sniklas      bfd_byte *contents;
2517fddef416Sniklas      Elf_Internal_Rela *relocs;
2518fddef416Sniklas      Elf_Internal_Sym *local_syms;
2519fddef416Sniklas      asection **local_sections;
2520fddef416Sniklas {
2521fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2522fddef416Sniklas   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2523fddef416Sniklas   Elf_Internal_Rela *rel, *relend;
2524fddef416Sniklas   /* Assume success.  */
2525d2201f2fSdrahn   bfd_boolean ret = TRUE;
2526d2201f2fSdrahn 
2527*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab = m32r_elf_hash_table (info);
2528*cf2f2c56Smiod   bfd *dynobj;
2529*cf2f2c56Smiod   bfd_vma *local_got_offsets;
2530*cf2f2c56Smiod   asection *sgot, *splt, *sreloc;
2531*cf2f2c56Smiod 
2532*cf2f2c56Smiod   dynobj = htab->root.dynobj;
2533*cf2f2c56Smiod   local_got_offsets = elf_local_got_offsets (input_bfd);
2534*cf2f2c56Smiod 
2535*cf2f2c56Smiod   sgot = htab->sgot;
2536*cf2f2c56Smiod   splt = htab->splt;
2537*cf2f2c56Smiod   sreloc = NULL;
2538fddef416Sniklas 
2539fddef416Sniklas   rel = relocs;
2540fddef416Sniklas   relend = relocs + input_section->reloc_count;
2541fddef416Sniklas   for (; rel < relend; rel++)
2542fddef416Sniklas     {
2543fddef416Sniklas       int r_type;
2544fddef416Sniklas       reloc_howto_type *howto;
2545fddef416Sniklas       unsigned long r_symndx;
2546*cf2f2c56Smiod       struct elf_link_hash_entry *h;
2547fddef416Sniklas       /* We can't modify r_addend here as elf_link_input_bfd has an assert to
2548fddef416Sniklas          ensure it's zero (we use REL relocs, not RELA).  Therefore this
2549fddef416Sniklas          should be assigning zero to `addend', but for clarity we use
2550fddef416Sniklas          `r_addend'.  */
2551fddef416Sniklas       bfd_vma addend = rel->r_addend;
2552fddef416Sniklas       bfd_vma offset = rel->r_offset;
2553fddef416Sniklas       Elf_Internal_Sym *sym;
2554fddef416Sniklas       asection *sec;
2555fddef416Sniklas       const char *sym_name;
2556fddef416Sniklas       bfd_reloc_status_type r;
2557fddef416Sniklas       const char *errmsg = NULL;
2558*cf2f2c56Smiod       bfd_boolean use_rel = FALSE;
2559fddef416Sniklas 
2560f7cc78ecSespie       h = NULL;
2561fddef416Sniklas       r_type = ELF32_R_TYPE (rel->r_info);
2562fddef416Sniklas       if (r_type < 0 || r_type >= (int) R_M32R_max)
2563fddef416Sniklas 	{
2564f7cc78ecSespie 	  (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
2565d2201f2fSdrahn 				 bfd_archive_filename (input_bfd),
2566fddef416Sniklas 				 (int) r_type);
2567fddef416Sniklas 	  bfd_set_error (bfd_error_bad_value);
2568d2201f2fSdrahn 	  ret = FALSE;
2569fddef416Sniklas 	  continue;
2570fddef416Sniklas 	}
2571fddef416Sniklas 
2572f7cc78ecSespie       if (r_type == R_M32R_GNU_VTENTRY
2573*cf2f2c56Smiod           || r_type == R_M32R_GNU_VTINHERIT
2574*cf2f2c56Smiod           || r_type == R_M32R_NONE
2575*cf2f2c56Smiod           || r_type == R_M32R_RELA_GNU_VTENTRY
2576*cf2f2c56Smiod           || r_type == R_M32R_RELA_GNU_VTINHERIT)
2577f7cc78ecSespie         continue;
2578f7cc78ecSespie 
2579*cf2f2c56Smiod       if (r_type <= R_M32R_GNU_VTENTRY)
2580*cf2f2c56Smiod         use_rel = TRUE;
2581*cf2f2c56Smiod 
2582fddef416Sniklas       howto = m32r_elf_howto_table + r_type;
2583fddef416Sniklas       r_symndx = ELF32_R_SYM (rel->r_info);
2584fddef416Sniklas 
2585*cf2f2c56Smiod       if (info->relocatable && (use_rel == TRUE))
2586fddef416Sniklas 	{
2587*cf2f2c56Smiod 	  /* This is a relocatable link.  We don't have to change
2588fddef416Sniklas 	     anything, unless the reloc is against a section symbol,
2589fddef416Sniklas 	     in which case we have to adjust according to where the
2590fddef416Sniklas 	     section symbol winds up in the output section.  */
2591fddef416Sniklas 	  sec = NULL;
2592fddef416Sniklas 	  if (r_symndx >= symtab_hdr->sh_info)
2593fddef416Sniklas 	    {
2594fddef416Sniklas 	      /* External symbol.  */
2595fddef416Sniklas 	      continue;
2596fddef416Sniklas 	    }
2597fddef416Sniklas 
2598fddef416Sniklas 	  /* Local symbol.  */
2599fddef416Sniklas 	  sym = local_syms + r_symndx;
2600fddef416Sniklas 	  sym_name = "<local symbol>";
2601fddef416Sniklas 	  /* STT_SECTION: symbol is associated with a section.  */
2602fddef416Sniklas 	  if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
2603fddef416Sniklas 	    {
2604fddef416Sniklas 	      /* Symbol isn't associated with a section.  Nothing to do.  */
2605fddef416Sniklas 	      continue;
2606fddef416Sniklas 	    }
2607fddef416Sniklas 
2608fddef416Sniklas 	  sec = local_sections[r_symndx];
2609fddef416Sniklas 	  addend += sec->output_offset + sym->st_value;
2610fddef416Sniklas 
2611fddef416Sniklas 	  /* If partial_inplace, we need to store any additional addend
2612fddef416Sniklas 	     back in the section.  */
2613fddef416Sniklas 	  if (! howto->partial_inplace)
2614fddef416Sniklas 	    continue;
2615fddef416Sniklas 	  /* ??? Here is a nice place to call a special_function
2616fddef416Sniklas 	     like handler.  */
2617fddef416Sniklas 	  if (r_type != R_M32R_HI16_SLO && r_type != R_M32R_HI16_ULO)
2618fddef416Sniklas 	    r = _bfd_relocate_contents (howto, input_bfd,
2619fddef416Sniklas 					addend, contents + offset);
2620fddef416Sniklas 	  else
2621fddef416Sniklas 	    {
2622fddef416Sniklas 	      Elf_Internal_Rela *lorel;
2623fddef416Sniklas 
2624fddef416Sniklas 	      /* We allow an arbitrary number of HI16 relocs before the
2625fddef416Sniklas 		 LO16 reloc.  This permits gcc to emit the HI and LO relocs
2626fddef416Sniklas 		 itself.  */
2627fddef416Sniklas 	      for (lorel = rel + 1;
2628fddef416Sniklas 		   (lorel < relend
2629fddef416Sniklas 		    && (ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_SLO
2630fddef416Sniklas 			|| ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_ULO));
2631fddef416Sniklas 		   lorel++)
2632fddef416Sniklas 		continue;
2633fddef416Sniklas 	      if (lorel < relend
2634fddef416Sniklas 		  && ELF32_R_TYPE (lorel->r_info) == R_M32R_LO16)
2635fddef416Sniklas 		{
2636fddef416Sniklas 		  m32r_elf_relocate_hi16 (input_bfd, r_type, rel, lorel,
2637fddef416Sniklas 					  contents, addend);
2638fddef416Sniklas 		  r = bfd_reloc_ok;
2639fddef416Sniklas 		}
2640fddef416Sniklas 	      else
2641fddef416Sniklas 		r = _bfd_relocate_contents (howto, input_bfd,
2642fddef416Sniklas 					    addend, contents + offset);
2643fddef416Sniklas 	    }
2644fddef416Sniklas 	}
2645fddef416Sniklas       else
2646fddef416Sniklas 	{
2647fddef416Sniklas 	  bfd_vma relocation;
2648fddef416Sniklas 
2649fddef416Sniklas 	  /* This is a final link.  */
2650fddef416Sniklas 	  sym = NULL;
2651fddef416Sniklas 	  sec = NULL;
2652*cf2f2c56Smiod           h = NULL;
2653fddef416Sniklas 
2654fddef416Sniklas 	  if (r_symndx < symtab_hdr->sh_info)
2655fddef416Sniklas 	    {
2656fddef416Sniklas 	      /* Local symbol.  */
2657fddef416Sniklas 	      sym = local_syms + r_symndx;
2658fddef416Sniklas 	      sec = local_sections[r_symndx];
2659fddef416Sniklas 	      sym_name = "<local symbol>";
2660*cf2f2c56Smiod 
2661*cf2f2c56Smiod               if (use_rel == FALSE)
2662*cf2f2c56Smiod                 {
2663*cf2f2c56Smiod 	          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2664d2201f2fSdrahn 	          addend = rel->r_addend;
2665*cf2f2c56Smiod 
2666*cf2f2c56Smiod                   if (info->relocatable)
2667*cf2f2c56Smiod                     {
2668*cf2f2c56Smiod                       /* This is a relocatable link.  We don't have to change
2669*cf2f2c56Smiod                          anything, unless the reloc is against a section symbol,
2670*cf2f2c56Smiod                          in which case we have to adjust according to where the
2671*cf2f2c56Smiod                          section symbol winds up in the output section.  */
2672*cf2f2c56Smiod                       if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2673*cf2f2c56Smiod                         rel->r_addend += sec->output_offset + sym->st_value;
2674*cf2f2c56Smiod 
2675*cf2f2c56Smiod                       continue;
2676*cf2f2c56Smiod                     }
2677*cf2f2c56Smiod                 }
2678*cf2f2c56Smiod               else
2679*cf2f2c56Smiod                 {
2680fddef416Sniklas 	          relocation = (sec->output_section->vma
2681fddef416Sniklas 			        + sec->output_offset
2682fddef416Sniklas 			        + sym->st_value);
2683*cf2f2c56Smiod                 }
2684fddef416Sniklas 	    }
2685fddef416Sniklas 	  else
2686fddef416Sniklas 	    {
2687fddef416Sniklas 	      /* External symbol.  */
2688*cf2f2c56Smiod               if (info->relocatable && (use_rel == FALSE))
2689*cf2f2c56Smiod                 continue;
2690*cf2f2c56Smiod 
2691fddef416Sniklas 	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2692fddef416Sniklas 	      while (h->root.type == bfd_link_hash_indirect
2693fddef416Sniklas 		     || h->root.type == bfd_link_hash_warning)
2694fddef416Sniklas 		h = (struct elf_link_hash_entry *) h->root.u.i.link;
2695fddef416Sniklas 	      sym_name = h->root.root.string;
2696fddef416Sniklas 
2697fddef416Sniklas 	      if (h->root.type == bfd_link_hash_defined
2698fddef416Sniklas 		  || h->root.type == bfd_link_hash_defweak)
2699fddef416Sniklas 		{
2700*cf2f2c56Smiod 	          bfd_boolean dyn;
2701fddef416Sniklas 		  sec = h->root.u.def.section;
2702*cf2f2c56Smiod 
2703*cf2f2c56Smiod 	          dyn = htab->root.dynamic_sections_created;
2704*cf2f2c56Smiod                   sec = h->root.u.def.section;
2705*cf2f2c56Smiod                   if (r_type == R_M32R_GOTPC24
2706*cf2f2c56Smiod                       || (r_type == R_M32R_GOTPC_HI_ULO
2707*cf2f2c56Smiod                           || r_type == R_M32R_GOTPC_HI_SLO
2708*cf2f2c56Smiod                           || r_type == R_M32R_GOTPC_LO)
2709*cf2f2c56Smiod                       || (r_type == R_M32R_26_PLTREL
2710*cf2f2c56Smiod                           && h->plt.offset != (bfd_vma) -1)
2711*cf2f2c56Smiod                       || ((r_type == R_M32R_GOT24
2712*cf2f2c56Smiod                            || r_type == R_M32R_GOT16_HI_ULO
2713*cf2f2c56Smiod                            || r_type == R_M32R_GOT16_HI_SLO
2714*cf2f2c56Smiod                            || r_type == R_M32R_GOT16_LO)
2715*cf2f2c56Smiod                           && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
2716*cf2f2c56Smiod 							      info->shared, h)
2717*cf2f2c56Smiod                           && (! info->shared
2718*cf2f2c56Smiod                               || (! info->symbolic && h->dynindx != -1)
2719*cf2f2c56Smiod                               || (h->elf_link_hash_flags
2720*cf2f2c56Smiod                                   & ELF_LINK_HASH_DEF_REGULAR) == 0))
2721*cf2f2c56Smiod                       || (info->shared
2722*cf2f2c56Smiod                           && ((! info->symbolic && h->dynindx != -1)
2723*cf2f2c56Smiod                               || (h->elf_link_hash_flags
2724*cf2f2c56Smiod                                   & ELF_LINK_HASH_DEF_REGULAR) == 0)
2725*cf2f2c56Smiod                           && (((r_type == R_M32R_16_RELA
2726*cf2f2c56Smiod                               || r_type == R_M32R_32_RELA
2727*cf2f2c56Smiod                               || r_type == R_M32R_24_RELA
2728*cf2f2c56Smiod                               || r_type == R_M32R_HI16_ULO_RELA
2729*cf2f2c56Smiod                               || r_type == R_M32R_HI16_SLO_RELA
2730*cf2f2c56Smiod                               || r_type == R_M32R_LO16_RELA)
2731*cf2f2c56Smiod 			          && (h->elf_link_hash_flags
2732*cf2f2c56Smiod 				      & ELF_LINK_FORCED_LOCAL) == 0)
2733*cf2f2c56Smiod                               || r_type == R_M32R_10_PCREL_RELA
2734*cf2f2c56Smiod                               || r_type == R_M32R_18_PCREL_RELA
2735*cf2f2c56Smiod                               || r_type == R_M32R_26_PCREL_RELA)
2736*cf2f2c56Smiod                           && ((input_section->flags & SEC_ALLOC) != 0
2737*cf2f2c56Smiod                               /* DWARF will emit R_M32R_16(24,32) relocations
2738*cf2f2c56Smiod                                  in its sections against symbols defined
2739*cf2f2c56Smiod                                  externally in shared libraries.  We can't do
2740*cf2f2c56Smiod                                  anything with them here.  */
2741*cf2f2c56Smiod                               || ((input_section->flags & SEC_DEBUGGING) != 0
2742*cf2f2c56Smiod                                   && (h->elf_link_hash_flags
2743*cf2f2c56Smiod                                       & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))
2744*cf2f2c56Smiod                     {
2745*cf2f2c56Smiod                       /* In these cases, we don't need the relocation
2746*cf2f2c56Smiod                          value.  We check specially because in some
2747*cf2f2c56Smiod                          obscure cases sec->output_section will be NULL.  */
2748fddef416Sniklas                       relocation = 0;
2749*cf2f2c56Smiod                     }
2750*cf2f2c56Smiod 		  else if (sec->output_section == NULL)
2751*cf2f2c56Smiod                     {
2752*cf2f2c56Smiod                       (*_bfd_error_handler)
2753*cf2f2c56Smiod                         (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
2754*cf2f2c56Smiod                          bfd_get_filename (input_bfd), h->root.root.string,
2755*cf2f2c56Smiod                          bfd_get_section_name (input_bfd, input_section));
2756*cf2f2c56Smiod 
2757*cf2f2c56Smiod 		       relocation = 0;
2758*cf2f2c56Smiod                     }
2759fddef416Sniklas 		  else
2760fddef416Sniklas 		    relocation = (h->root.u.def.value
2761fddef416Sniklas 				  + sec->output_section->vma
2762fddef416Sniklas 				  + sec->output_offset);
2763fddef416Sniklas 		}
2764fddef416Sniklas 	      else if (h->root.type == bfd_link_hash_undefweak)
2765fddef416Sniklas 		relocation = 0;
2766*cf2f2c56Smiod               else if (info->unresolved_syms_in_objects == RM_IGNORE
2767*cf2f2c56Smiod                        && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
2768*cf2f2c56Smiod                 relocation = 0;
2769fddef416Sniklas 	      else
2770fddef416Sniklas 		{
2771fddef416Sniklas 		  if (! ((*info->callbacks->undefined_symbol)
2772fddef416Sniklas 			 (info, h->root.root.string, input_bfd,
2773*cf2f2c56Smiod 			  input_section, offset,
2774*cf2f2c56Smiod                           (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
2775*cf2f2c56Smiod                            || ELF_ST_VISIBILITY (h->other)))))
2776d2201f2fSdrahn 		    return FALSE;
2777fddef416Sniklas 		  relocation = 0;
2778fddef416Sniklas 		}
2779fddef416Sniklas 	    }
2780fddef416Sniklas 
2781fddef416Sniklas 	  /* Sanity check the address.  */
2782fddef416Sniklas 	  if (offset > input_section->_raw_size)
2783fddef416Sniklas 	    {
2784fddef416Sniklas 	      r = bfd_reloc_outofrange;
2785fddef416Sniklas 	      goto check_reloc;
2786fddef416Sniklas 	    }
2787fddef416Sniklas 
2788fddef416Sniklas 	  switch ((int) r_type)
2789fddef416Sniklas 	    {
2790*cf2f2c56Smiod             case R_M32R_GOTPC24:
2791*cf2f2c56Smiod               /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
2792*cf2f2c56Smiod                  ld24 rx,#_GLOBAL_OFFSET_TABLE_
2793*cf2f2c56Smiod                */
2794*cf2f2c56Smiod              relocation = sgot->output_section->vma;
2795*cf2f2c56Smiod              break;
2796*cf2f2c56Smiod 
2797*cf2f2c56Smiod             case R_M32R_GOTPC_HI_ULO:
2798*cf2f2c56Smiod             case R_M32R_GOTPC_HI_SLO:
2799*cf2f2c56Smiod             case R_M32R_GOTPC_LO:
2800*cf2f2c56Smiod               {
2801*cf2f2c56Smiod                 /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
2802*cf2f2c56Smiod                    bl .+4
2803*cf2f2c56Smiod                    seth rx,#high(_GLOBAL_OFFSET_TABLE_)
2804*cf2f2c56Smiod                    or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
2805*cf2f2c56Smiod                    or
2806*cf2f2c56Smiod                    bl .+4
2807*cf2f2c56Smiod                    seth rx,#shigh(_GLOBAL_OFFSET_TABLE_)
2808*cf2f2c56Smiod                    add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
2809*cf2f2c56Smiod                  */
2810*cf2f2c56Smiod                 relocation = sgot->output_section->vma;
2811*cf2f2c56Smiod                 relocation -= (input_section->output_section->vma
2812*cf2f2c56Smiod                                + input_section->output_offset
2813*cf2f2c56Smiod                                + rel->r_offset);
2814*cf2f2c56Smiod                 if ((r_type == R_M32R_GOTPC_HI_SLO)
2815*cf2f2c56Smiod                      && ((relocation + rel->r_addend) & 0x8000))
2816*cf2f2c56Smiod                   rel->r_addend += 0x10000;
2817*cf2f2c56Smiod 
2818*cf2f2c56Smiod                 break;
2819*cf2f2c56Smiod               }
2820*cf2f2c56Smiod             case R_M32R_GOT16_HI_ULO:
2821*cf2f2c56Smiod             case R_M32R_GOT16_HI_SLO:
2822*cf2f2c56Smiod             case R_M32R_GOT16_LO:
2823*cf2f2c56Smiod               /* Fall through.  */
2824*cf2f2c56Smiod             case R_M32R_GOT24:
2825*cf2f2c56Smiod               /* Relocation is to the entry for this symbol in the global
2826*cf2f2c56Smiod                  offset table.  */
2827*cf2f2c56Smiod               BFD_ASSERT (sgot != NULL);
2828*cf2f2c56Smiod 
2829*cf2f2c56Smiod               if (h != NULL)
2830*cf2f2c56Smiod                 {
2831*cf2f2c56Smiod                   bfd_boolean dyn;
2832*cf2f2c56Smiod                   bfd_vma off;
2833*cf2f2c56Smiod 
2834*cf2f2c56Smiod                   off = h->got.offset;
2835*cf2f2c56Smiod                   BFD_ASSERT (off != (bfd_vma) -1);
2836*cf2f2c56Smiod 
2837*cf2f2c56Smiod                   dyn = htab->root.dynamic_sections_created;
2838*cf2f2c56Smiod                   if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
2839*cf2f2c56Smiod                       || (info->shared
2840*cf2f2c56Smiod                           && (info->symbolic
2841*cf2f2c56Smiod                               || h->dynindx == -1
2842*cf2f2c56Smiod                               || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
2843*cf2f2c56Smiod                           && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
2844*cf2f2c56Smiod                     {
2845*cf2f2c56Smiod                       /* This is actually a static link, or it is a
2846*cf2f2c56Smiod                          -Bsymbolic link and the symbol is defined
2847*cf2f2c56Smiod                          locally, or the symbol was forced to be local
2848*cf2f2c56Smiod                          because of a version file.  We must initialize
2849*cf2f2c56Smiod                          this entry in the global offset table.  Since the
2850*cf2f2c56Smiod                          offset must always be a multiple of 4, we use the
2851*cf2f2c56Smiod                          least significant bit to record whether we have
2852*cf2f2c56Smiod                          initialized it already.
2853*cf2f2c56Smiod 
2854*cf2f2c56Smiod                          When doing a dynamic link, we create a .rela.got
2855*cf2f2c56Smiod                          relocation entry to initialize the value.  This
2856*cf2f2c56Smiod                          is done in the finish_dynamic_symbol routine.  */
2857*cf2f2c56Smiod                       if ((off & 1) != 0)
2858*cf2f2c56Smiod                         off &= ~1;
2859*cf2f2c56Smiod                       else
2860*cf2f2c56Smiod                         {
2861*cf2f2c56Smiod                           bfd_put_32 (output_bfd, relocation,
2862*cf2f2c56Smiod                                       sgot->contents + off);
2863*cf2f2c56Smiod                           h->got.offset |= 1;
2864*cf2f2c56Smiod                         }
2865*cf2f2c56Smiod                     }
2866*cf2f2c56Smiod 
2867*cf2f2c56Smiod                   relocation = sgot->output_offset + off;
2868*cf2f2c56Smiod                 }
2869*cf2f2c56Smiod               else
2870*cf2f2c56Smiod                 {
2871*cf2f2c56Smiod                   bfd_vma off;
2872*cf2f2c56Smiod                   bfd_byte *loc;
2873*cf2f2c56Smiod 
2874*cf2f2c56Smiod                   BFD_ASSERT (local_got_offsets != NULL
2875*cf2f2c56Smiod                               && local_got_offsets[r_symndx] != (bfd_vma) -1);
2876*cf2f2c56Smiod 
2877*cf2f2c56Smiod                   off = local_got_offsets[r_symndx];
2878*cf2f2c56Smiod 
2879*cf2f2c56Smiod                   /* The offset must always be a multiple of 4.  We use
2880*cf2f2c56Smiod                      the least significant bit to record whether we have
2881*cf2f2c56Smiod                      already processed this entry.  */
2882*cf2f2c56Smiod                   if ((off & 1) != 0)
2883*cf2f2c56Smiod                     off &= ~1;
2884*cf2f2c56Smiod                   else
2885*cf2f2c56Smiod                     {
2886*cf2f2c56Smiod                       bfd_put_32 (output_bfd, relocation, sgot->contents + off);
2887*cf2f2c56Smiod 
2888*cf2f2c56Smiod                       if (info->shared)
2889*cf2f2c56Smiod                         {
2890*cf2f2c56Smiod                           asection *srelgot;
2891*cf2f2c56Smiod                           Elf_Internal_Rela outrel;
2892*cf2f2c56Smiod 
2893*cf2f2c56Smiod                           /* We need to generate a R_M32R_RELATIVE reloc
2894*cf2f2c56Smiod                              for the dynamic linker.  */
2895*cf2f2c56Smiod                           srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
2896*cf2f2c56Smiod                           BFD_ASSERT (srelgot != NULL);
2897*cf2f2c56Smiod 
2898*cf2f2c56Smiod                           outrel.r_offset = (sgot->output_section->vma
2899*cf2f2c56Smiod                                              + sgot->output_offset
2900*cf2f2c56Smiod                                              + off);
2901*cf2f2c56Smiod                           outrel.r_info = ELF32_R_INFO (0, R_M32R_RELATIVE);
2902*cf2f2c56Smiod                           outrel.r_addend = relocation;
2903*cf2f2c56Smiod                           loc = srelgot->contents;
2904*cf2f2c56Smiod                           loc += srelgot->reloc_count * sizeof(Elf32_External_Rela);
2905*cf2f2c56Smiod                           bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
2906*cf2f2c56Smiod                           ++srelgot->reloc_count;
2907*cf2f2c56Smiod                         }
2908*cf2f2c56Smiod 
2909*cf2f2c56Smiod                       local_got_offsets[r_symndx] |= 1;
2910*cf2f2c56Smiod                     }
2911*cf2f2c56Smiod 
2912*cf2f2c56Smiod                   relocation = sgot->output_offset + off;
2913*cf2f2c56Smiod                 }
2914*cf2f2c56Smiod               if ((r_type == R_M32R_GOT16_HI_SLO)
2915*cf2f2c56Smiod                   && ((relocation + rel->r_addend) & 0x8000))
2916*cf2f2c56Smiod                 rel->r_addend += 0x10000;
2917*cf2f2c56Smiod 
2918*cf2f2c56Smiod               break;
2919*cf2f2c56Smiod 
2920*cf2f2c56Smiod             case R_M32R_26_PLTREL:
2921*cf2f2c56Smiod               /* Relocation is to the entry for this symbol in the
2922*cf2f2c56Smiod                  procedure linkage table.  */
2923*cf2f2c56Smiod 
2924*cf2f2c56Smiod               /* The native assembler will generate a 26_PLTREL reloc
2925*cf2f2c56Smiod                  for a local symbol if you assemble a call from one
2926*cf2f2c56Smiod                  section to another when using -K pic. */
2927*cf2f2c56Smiod               if (h == NULL)
2928*cf2f2c56Smiod                 break;
2929*cf2f2c56Smiod 
2930*cf2f2c56Smiod               //if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
2931*cf2f2c56Smiod               //    || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
2932*cf2f2c56Smiod               //  break;
2933*cf2f2c56Smiod               if (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)
2934*cf2f2c56Smiod                 break;
2935*cf2f2c56Smiod 
2936*cf2f2c56Smiod               if (h->plt.offset == (bfd_vma) -1)
2937*cf2f2c56Smiod                 {
2938*cf2f2c56Smiod                   /* We didn't make a PLT entry for this symbol.  This
2939*cf2f2c56Smiod                      happens when statically linking PIC code, or when
2940*cf2f2c56Smiod                      using -Bsymbolic.  */
2941*cf2f2c56Smiod                   break;
2942*cf2f2c56Smiod                 }
2943*cf2f2c56Smiod 
2944*cf2f2c56Smiod               relocation = (splt->output_section->vma
2945*cf2f2c56Smiod                             + splt->output_offset
2946*cf2f2c56Smiod                             + h->plt.offset);
2947*cf2f2c56Smiod               break;
2948*cf2f2c56Smiod 
2949*cf2f2c56Smiod             case R_M32R_HI16_SLO_RELA:
2950*cf2f2c56Smiod               {
2951*cf2f2c56Smiod                  if ((relocation + rel->r_addend) & 0x8000)
2952*cf2f2c56Smiod                    {
2953*cf2f2c56Smiod                      rel->r_addend += 0x10000;
2954*cf2f2c56Smiod                    }
2955*cf2f2c56Smiod               }
2956*cf2f2c56Smiod               /* Fall through.  */
2957*cf2f2c56Smiod             case R_M32R_16_RELA:
2958*cf2f2c56Smiod             case R_M32R_24_RELA:
2959*cf2f2c56Smiod             case R_M32R_32_RELA:
2960*cf2f2c56Smiod             case R_M32R_18_PCREL_RELA:
2961*cf2f2c56Smiod             case R_M32R_26_PCREL_RELA:
2962*cf2f2c56Smiod             case R_M32R_HI16_ULO_RELA:
2963*cf2f2c56Smiod             case R_M32R_LO16_RELA:
2964*cf2f2c56Smiod             case R_M32R_SDA16_RELA:
2965*cf2f2c56Smiod               if (info->shared
2966*cf2f2c56Smiod                   && r_symndx != 0
2967*cf2f2c56Smiod                   && (input_section->flags & SEC_ALLOC) != 0
2968*cf2f2c56Smiod                   && ((r_type != R_M32R_18_PCREL_RELA
2969*cf2f2c56Smiod                        && r_type != R_M32R_26_PCREL_RELA)
2970*cf2f2c56Smiod                       || (h != NULL
2971*cf2f2c56Smiod                           && h->dynindx != -1
2972*cf2f2c56Smiod                           && (! info->symbolic
2973*cf2f2c56Smiod                               || (h->elf_link_hash_flags
2974*cf2f2c56Smiod                                   & ELF_LINK_HASH_DEF_REGULAR) == 0))))
2975*cf2f2c56Smiod                 {
2976*cf2f2c56Smiod                   Elf_Internal_Rela outrel;
2977*cf2f2c56Smiod                   bfd_boolean skip, relocate;
2978*cf2f2c56Smiod                   bfd_byte *loc;
2979*cf2f2c56Smiod 
2980*cf2f2c56Smiod                   /* When generating a shared object, these relocations
2981*cf2f2c56Smiod                      are copied into the output file to be resolved at run
2982*cf2f2c56Smiod                      time.  */
2983*cf2f2c56Smiod 
2984*cf2f2c56Smiod                   if (sreloc == NULL)
2985*cf2f2c56Smiod                     {
2986*cf2f2c56Smiod                       const char *name;
2987*cf2f2c56Smiod 
2988*cf2f2c56Smiod                       name = (bfd_elf_string_from_elf_section
2989*cf2f2c56Smiod                               (input_bfd,
2990*cf2f2c56Smiod                                elf_elfheader (input_bfd)->e_shstrndx,
2991*cf2f2c56Smiod                                elf_section_data (input_section)->rel_hdr.sh_name));
2992*cf2f2c56Smiod                       if (name == NULL)
2993*cf2f2c56Smiod                         return FALSE;
2994*cf2f2c56Smiod 
2995*cf2f2c56Smiod                       BFD_ASSERT (strncmp (name, ".rela", 5) == 0
2996*cf2f2c56Smiod                                   && strcmp (bfd_get_section_name (input_bfd,
2997*cf2f2c56Smiod                                                                    input_section),
2998*cf2f2c56Smiod                                              name + 5) == 0);
2999*cf2f2c56Smiod 
3000*cf2f2c56Smiod                       sreloc = bfd_get_section_by_name (dynobj, name);
3001*cf2f2c56Smiod                       BFD_ASSERT (sreloc != NULL);
3002*cf2f2c56Smiod                     }
3003*cf2f2c56Smiod 
3004*cf2f2c56Smiod                   skip = FALSE;
3005*cf2f2c56Smiod                   relocate = FALSE;
3006*cf2f2c56Smiod 
3007*cf2f2c56Smiod                   outrel.r_offset = _bfd_elf_section_offset (output_bfd,
3008*cf2f2c56Smiod                                                              info,
3009*cf2f2c56Smiod                                                              input_section,
3010*cf2f2c56Smiod                                                              rel->r_offset);
3011*cf2f2c56Smiod                   if (outrel.r_offset == (bfd_vma) -1)
3012*cf2f2c56Smiod                     skip = TRUE;
3013*cf2f2c56Smiod                   else if (outrel.r_offset == (bfd_vma) -2)
3014*cf2f2c56Smiod                     skip = TRUE, relocate = TRUE;
3015*cf2f2c56Smiod                   outrel.r_offset += (input_section->output_section->vma
3016*cf2f2c56Smiod                                       + input_section->output_offset);
3017*cf2f2c56Smiod 
3018*cf2f2c56Smiod                   if (skip)
3019*cf2f2c56Smiod                     memset (&outrel, 0, sizeof outrel);
3020*cf2f2c56Smiod                   else if (r_type == R_M32R_18_PCREL_RELA
3021*cf2f2c56Smiod                            || r_type == R_M32R_26_PCREL_RELA)
3022*cf2f2c56Smiod                     {
3023*cf2f2c56Smiod                       BFD_ASSERT (h != NULL && h->dynindx != -1);
3024*cf2f2c56Smiod                       outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
3025*cf2f2c56Smiod                       outrel.r_addend = rel->r_addend;
3026*cf2f2c56Smiod                     }
3027*cf2f2c56Smiod                   else
3028*cf2f2c56Smiod                     {
3029*cf2f2c56Smiod                     /* h->dynindx may be -1 if this symbol was marked to
3030*cf2f2c56Smiod                        become local.  */
3031*cf2f2c56Smiod                     if (h == NULL
3032*cf2f2c56Smiod                         || ((info->symbolic || h->dynindx == -1)
3033*cf2f2c56Smiod                              && (h->elf_link_hash_flags
3034*cf2f2c56Smiod                                  & ELF_LINK_HASH_DEF_REGULAR) != 0))
3035*cf2f2c56Smiod                       {
3036*cf2f2c56Smiod                         relocate = TRUE;
3037*cf2f2c56Smiod                         outrel.r_info = ELF32_R_INFO (0, R_M32R_RELATIVE);
3038*cf2f2c56Smiod                         outrel.r_addend = relocation + rel->r_addend;
3039*cf2f2c56Smiod                       }
3040*cf2f2c56Smiod                     else
3041*cf2f2c56Smiod                       {
3042*cf2f2c56Smiod                         BFD_ASSERT (h->dynindx != -1);
3043*cf2f2c56Smiod                         outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
3044*cf2f2c56Smiod                         outrel.r_addend = relocation + rel->r_addend;
3045*cf2f2c56Smiod                       }
3046*cf2f2c56Smiod                     }
3047*cf2f2c56Smiod 
3048*cf2f2c56Smiod                   loc = sreloc->contents;
3049*cf2f2c56Smiod                   loc += sreloc->reloc_count * sizeof(Elf32_External_Rela);
3050*cf2f2c56Smiod                   bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
3051*cf2f2c56Smiod                   ++sreloc->reloc_count;
3052*cf2f2c56Smiod 
3053*cf2f2c56Smiod                   /* If this reloc is against an external symbol, we do
3054*cf2f2c56Smiod                      not want to fiddle with the addend.  Otherwise, we
3055*cf2f2c56Smiod                      need to include the symbol value so that it becomes
3056*cf2f2c56Smiod                      an addend for the dynamic reloc.  */
3057*cf2f2c56Smiod                   if (! relocate)
3058*cf2f2c56Smiod                     continue;
3059*cf2f2c56Smiod                 }
3060*cf2f2c56Smiod               break;
3061*cf2f2c56Smiod 
3062fddef416Sniklas 	    case (int) R_M32R_10_PCREL :
3063fddef416Sniklas 	      r = m32r_elf_do_10_pcrel_reloc (input_bfd, howto, input_section,
3064fddef416Sniklas 					      contents, offset,
3065fddef416Sniklas 					      sec, relocation, addend);
3066*cf2f2c56Smiod               goto check_reloc;
3067fddef416Sniklas 
3068fddef416Sniklas 	    case (int) R_M32R_HI16_SLO :
3069fddef416Sniklas 	    case (int) R_M32R_HI16_ULO :
3070fddef416Sniklas 	      {
3071fddef416Sniklas 		Elf_Internal_Rela *lorel;
3072fddef416Sniklas 
3073fddef416Sniklas 		/* We allow an arbitrary number of HI16 relocs before the
3074fddef416Sniklas 		   LO16 reloc.  This permits gcc to emit the HI and LO relocs
3075fddef416Sniklas 		   itself.  */
3076fddef416Sniklas 		for (lorel = rel + 1;
3077fddef416Sniklas 		     (lorel < relend
3078fddef416Sniklas 		      && (ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_SLO
3079fddef416Sniklas 			  || ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_ULO));
3080fddef416Sniklas 		     lorel++)
3081fddef416Sniklas 		  continue;
3082fddef416Sniklas 		if (lorel < relend
3083fddef416Sniklas 		    && ELF32_R_TYPE (lorel->r_info) == R_M32R_LO16)
3084fddef416Sniklas 		  {
3085fddef416Sniklas 		    m32r_elf_relocate_hi16 (input_bfd, r_type, rel, lorel,
3086fddef416Sniklas 					    contents, relocation + addend);
3087fddef416Sniklas 		    r = bfd_reloc_ok;
3088fddef416Sniklas 		  }
3089fddef416Sniklas 		else
3090fddef416Sniklas 		  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3091fddef416Sniklas 						contents, offset,
3092fddef416Sniklas 						relocation, addend);
3093fddef416Sniklas 	      }
3094*cf2f2c56Smiod 
3095*cf2f2c56Smiod               goto check_reloc;
3096fddef416Sniklas 
3097fddef416Sniklas 	    case (int) R_M32R_SDA16 :
3098fddef416Sniklas 	      {
3099fddef416Sniklas 		const char *name;
3100fddef416Sniklas 
3101fddef416Sniklas 		BFD_ASSERT (sec != NULL);
3102fddef416Sniklas 		name = bfd_get_section_name (abfd, sec);
3103fddef416Sniklas 
3104fddef416Sniklas 		if (strcmp (name, ".sdata") == 0
3105fddef416Sniklas 		    || strcmp (name, ".sbss") == 0
3106fddef416Sniklas 		    || strcmp (name, ".scommon") == 0)
3107fddef416Sniklas 		  {
3108fddef416Sniklas 		    bfd_vma sda_base;
3109fddef416Sniklas 		    bfd *out_bfd = sec->output_section->owner;
3110fddef416Sniklas 
3111fddef416Sniklas 		    r = m32r_elf_final_sda_base (out_bfd, info,
3112fddef416Sniklas 						 &errmsg,
3113fddef416Sniklas 						 &sda_base);
3114fddef416Sniklas 		    if (r != bfd_reloc_ok)
3115fddef416Sniklas 		      {
3116d2201f2fSdrahn 			ret = FALSE;
3117fddef416Sniklas 			goto check_reloc;
3118fddef416Sniklas 		      }
3119fddef416Sniklas 
3120fddef416Sniklas 		    /* At this point `relocation' contains the object's
3121fddef416Sniklas 		       address.  */
3122fddef416Sniklas 		    relocation -= sda_base;
3123fddef416Sniklas 		    /* Now it contains the offset from _SDA_BASE_.  */
3124fddef416Sniklas 		  }
3125fddef416Sniklas 		else
3126fddef416Sniklas 		  {
3127d2201f2fSdrahn 		    (*_bfd_error_handler)
3128d2201f2fSdrahn 		      (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
3129d2201f2fSdrahn 		       bfd_archive_filename (input_bfd),
3130fddef416Sniklas 		       sym_name,
3131fddef416Sniklas 		       m32r_elf_howto_table[(int) r_type].name,
3132fddef416Sniklas 		       bfd_get_section_name (abfd, sec));
3133fddef416Sniklas 		    /*bfd_set_error (bfd_error_bad_value); ??? why? */
3134d2201f2fSdrahn 		    ret = FALSE;
3135fddef416Sniklas 		    continue;
3136fddef416Sniklas 		  }
3137fddef416Sniklas 	      }
3138fddef416Sniklas               /* fall through */
3139fddef416Sniklas 
3140*cf2f2c56Smiod 	    default : /* OLD_M32R_RELOC */
3141*cf2f2c56Smiod 
3142fddef416Sniklas 	      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3143fddef416Sniklas 					    contents, offset,
3144fddef416Sniklas 					    relocation, addend);
3145*cf2f2c56Smiod 	      goto check_reloc;
3146fddef416Sniklas 	    }
3147*cf2f2c56Smiod 
3148*cf2f2c56Smiod           r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3149*cf2f2c56Smiod                                         contents, rel->r_offset,
3150*cf2f2c56Smiod                                         relocation, rel->r_addend);
3151*cf2f2c56Smiod 
3152fddef416Sniklas 	}
3153fddef416Sniklas 
3154fddef416Sniklas     check_reloc:
3155fddef416Sniklas 
3156fddef416Sniklas       if (r != bfd_reloc_ok)
3157fddef416Sniklas 	{
3158fddef416Sniklas 	  /* FIXME: This should be generic enough to go in a utility.  */
3159fddef416Sniklas 	  const char *name;
3160fddef416Sniklas 
3161fddef416Sniklas 	  if (h != NULL)
3162fddef416Sniklas 	    name = h->root.root.string;
3163fddef416Sniklas 	  else
3164fddef416Sniklas 	    {
3165fddef416Sniklas 	      name = (bfd_elf_string_from_elf_section
3166fddef416Sniklas 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
3167fddef416Sniklas 	      if (name == NULL || *name == '\0')
3168fddef416Sniklas 		name = bfd_section_name (input_bfd, sec);
3169fddef416Sniklas 	    }
3170fddef416Sniklas 
3171fddef416Sniklas 	  if (errmsg != NULL)
3172fddef416Sniklas 	    goto common_error;
3173fddef416Sniklas 
3174fddef416Sniklas 	  switch (r)
3175fddef416Sniklas 	    {
3176fddef416Sniklas 	    case bfd_reloc_overflow:
3177fddef416Sniklas 	      if (! ((*info->callbacks->reloc_overflow)
3178fddef416Sniklas 		     (info, name, howto->name, (bfd_vma) 0,
3179fddef416Sniklas 		      input_bfd, input_section, offset)))
3180d2201f2fSdrahn 		return FALSE;
3181fddef416Sniklas 	      break;
3182fddef416Sniklas 
3183fddef416Sniklas 	    case bfd_reloc_undefined:
3184fddef416Sniklas 	      if (! ((*info->callbacks->undefined_symbol)
3185fddef416Sniklas 		     (info, name, input_bfd, input_section,
3186d2201f2fSdrahn 		      offset, TRUE)))
3187d2201f2fSdrahn 		return FALSE;
3188fddef416Sniklas 	      break;
3189fddef416Sniklas 
3190fddef416Sniklas 	    case bfd_reloc_outofrange:
3191f7cc78ecSespie 	      errmsg = _("internal error: out of range error");
3192fddef416Sniklas 	      goto common_error;
3193fddef416Sniklas 
3194fddef416Sniklas 	    case bfd_reloc_notsupported:
3195f7cc78ecSespie 	      errmsg = _("internal error: unsupported relocation error");
3196fddef416Sniklas 	      goto common_error;
3197fddef416Sniklas 
3198fddef416Sniklas 	    case bfd_reloc_dangerous:
3199f7cc78ecSespie 	      errmsg = _("internal error: dangerous error");
3200fddef416Sniklas 	      goto common_error;
3201fddef416Sniklas 
3202fddef416Sniklas 	    default:
3203f7cc78ecSespie 	      errmsg = _("internal error: unknown error");
3204fddef416Sniklas 	      /* fall through */
3205fddef416Sniklas 
3206fddef416Sniklas 	    common_error:
3207fddef416Sniklas 	      if (!((*info->callbacks->warning)
3208fddef416Sniklas 		    (info, errmsg, name, input_bfd, input_section,
3209fddef416Sniklas 		     offset)))
3210d2201f2fSdrahn 		return FALSE;
3211fddef416Sniklas 	      break;
3212fddef416Sniklas 	    }
3213fddef416Sniklas 	}
3214fddef416Sniklas     }
3215fddef416Sniklas 
3216fddef416Sniklas   return ret;
3217fddef416Sniklas }
3218*cf2f2c56Smiod 
3219*cf2f2c56Smiod /* Finish up dynamic symbol handling.  We set the contents of various
3220*cf2f2c56Smiod    dynamic sections here.  */
3221*cf2f2c56Smiod static bfd_boolean
m32r_elf_finish_dynamic_symbol(output_bfd,info,h,sym)3222*cf2f2c56Smiod m32r_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
3223*cf2f2c56Smiod      bfd *output_bfd;
3224*cf2f2c56Smiod      struct bfd_link_info *info;
3225*cf2f2c56Smiod      struct elf_link_hash_entry *h;
3226*cf2f2c56Smiod      Elf_Internal_Sym *sym;
3227*cf2f2c56Smiod {
3228*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
3229*cf2f2c56Smiod   bfd *dynobj;
3230*cf2f2c56Smiod   bfd_byte *loc;
3231*cf2f2c56Smiod 
3232*cf2f2c56Smiod #ifdef DEBUG_PIC
3233*cf2f2c56Smiod printf("m32r_elf_finish_dynamic_symbol()\n");
3234*cf2f2c56Smiod #endif
3235*cf2f2c56Smiod 
3236*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
3237*cf2f2c56Smiod   dynobj = htab->root.dynobj;
3238*cf2f2c56Smiod 
3239*cf2f2c56Smiod   if (h->plt.offset != (bfd_vma) -1)
3240*cf2f2c56Smiod     {
3241*cf2f2c56Smiod       asection *splt;
3242*cf2f2c56Smiod       asection *sgot;
3243*cf2f2c56Smiod       asection *srela;
3244*cf2f2c56Smiod 
3245*cf2f2c56Smiod       bfd_vma plt_index;
3246*cf2f2c56Smiod       bfd_vma got_offset;
3247*cf2f2c56Smiod       Elf_Internal_Rela rela;
3248*cf2f2c56Smiod 
3249*cf2f2c56Smiod       /* This symbol has an entry in the procedure linkage table.  Set
3250*cf2f2c56Smiod          it up.  */
3251*cf2f2c56Smiod 
3252*cf2f2c56Smiod       BFD_ASSERT (h->dynindx != -1);
3253*cf2f2c56Smiod 
3254*cf2f2c56Smiod       splt = htab->splt;
3255*cf2f2c56Smiod       sgot = htab->sgotplt;
3256*cf2f2c56Smiod       srela = htab->srelplt;
3257*cf2f2c56Smiod       BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
3258*cf2f2c56Smiod 
3259*cf2f2c56Smiod       /* Get the index in the procedure linkage table which
3260*cf2f2c56Smiod          corresponds to this symbol.  This is the index of this symbol
3261*cf2f2c56Smiod          in all the symbols for which we are making plt entries.  The
3262*cf2f2c56Smiod          first entry in the procedure linkage table is reserved.  */
3263*cf2f2c56Smiod       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
3264*cf2f2c56Smiod 
3265*cf2f2c56Smiod       /* Get the offset into the .got table of the entry that
3266*cf2f2c56Smiod         corresponds to this function.  Each .got entry is 4 bytes.
3267*cf2f2c56Smiod         The first three are reserved.  */
3268*cf2f2c56Smiod       got_offset = (plt_index + 3) * 4;
3269*cf2f2c56Smiod 
3270*cf2f2c56Smiod       /* Fill in the entry in the procedure linkage table.  */
3271*cf2f2c56Smiod       if (! info->shared)
3272*cf2f2c56Smiod         {
3273*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3274*cf2f2c56Smiod               (PLT_ENTRY_WORD0b
3275*cf2f2c56Smiod                + (((sgot->output_section->vma
3276*cf2f2c56Smiod                     + sgot->output_offset
3277*cf2f2c56Smiod                     + got_offset) >> 16) & 0xffff)),
3278*cf2f2c56Smiod               splt->contents + h->plt.offset);
3279*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3280*cf2f2c56Smiod               (PLT_ENTRY_WORD1b
3281*cf2f2c56Smiod                + ((sgot->output_section->vma
3282*cf2f2c56Smiod                    + sgot->output_offset
3283*cf2f2c56Smiod                    + got_offset) & 0xffff)),
3284*cf2f2c56Smiod               splt->contents + h->plt.offset + 4);
3285*cf2f2c56Smiod           bfd_put_32 (output_bfd, PLT_ENTRY_WORD2,
3286*cf2f2c56Smiod               splt->contents + h->plt.offset + 8);
3287*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3288*cf2f2c56Smiod               (PLT_ENTRY_WORD3
3289*cf2f2c56Smiod                + plt_index * sizeof (Elf32_External_Rela)),
3290*cf2f2c56Smiod               splt->contents + h->plt.offset + 12);
3291*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3292*cf2f2c56Smiod               (PLT_ENTRY_WORD4
3293*cf2f2c56Smiod                + (((unsigned int) ((- (h->plt.offset + 16)) >> 2)) & 0xffffff)),
3294*cf2f2c56Smiod               splt->contents + h->plt.offset + 16);
3295*cf2f2c56Smiod         }
3296*cf2f2c56Smiod       else
3297*cf2f2c56Smiod         {
3298*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3299*cf2f2c56Smiod               PLT_ENTRY_WORD0 + got_offset,
3300*cf2f2c56Smiod               splt->contents + h->plt.offset);
3301*cf2f2c56Smiod           bfd_put_32 (output_bfd, PLT_ENTRY_WORD1,
3302*cf2f2c56Smiod               splt->contents + h->plt.offset + 4);
3303*cf2f2c56Smiod           bfd_put_32 (output_bfd, PLT_ENTRY_WORD2,
3304*cf2f2c56Smiod               splt->contents + h->plt.offset + 8);
3305*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3306*cf2f2c56Smiod               (PLT_ENTRY_WORD3
3307*cf2f2c56Smiod                + plt_index * sizeof (Elf32_External_Rela)),
3308*cf2f2c56Smiod               splt->contents + h->plt.offset + 12);
3309*cf2f2c56Smiod           bfd_put_32 (output_bfd,
3310*cf2f2c56Smiod               (PLT_ENTRY_WORD4
3311*cf2f2c56Smiod                + (((unsigned int) ((- (h->plt.offset + 16)) >> 2)) & 0xffffff)),
3312*cf2f2c56Smiod               splt->contents + h->plt.offset + 16);
3313*cf2f2c56Smiod         }
3314*cf2f2c56Smiod 
3315*cf2f2c56Smiod       /* Fill in the entry in the global offset table.  */
3316*cf2f2c56Smiod       bfd_put_32 (output_bfd,
3317*cf2f2c56Smiod                   (splt->output_section->vma
3318*cf2f2c56Smiod                    + splt->output_offset
3319*cf2f2c56Smiod                    + h->plt.offset
3320*cf2f2c56Smiod                    + 12), /* same offset */
3321*cf2f2c56Smiod                   sgot->contents + got_offset);
3322*cf2f2c56Smiod 
3323*cf2f2c56Smiod       /* Fill in the entry in the .rela.plt section.  */
3324*cf2f2c56Smiod       rela.r_offset = (sgot->output_section->vma
3325*cf2f2c56Smiod                        + sgot->output_offset
3326*cf2f2c56Smiod                        + got_offset);
3327*cf2f2c56Smiod       rela.r_info = ELF32_R_INFO (h->dynindx, R_M32R_JMP_SLOT);
3328*cf2f2c56Smiod       rela.r_addend = 0;
3329*cf2f2c56Smiod       loc = srela->contents;
3330*cf2f2c56Smiod       loc += plt_index * sizeof(Elf32_External_Rela);
3331*cf2f2c56Smiod       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3332*cf2f2c56Smiod 
3333*cf2f2c56Smiod       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
3334*cf2f2c56Smiod         {
3335*cf2f2c56Smiod           /* Mark the symbol as undefined, rather than as defined in
3336*cf2f2c56Smiod              the .plt section.  Leave the value alone.  */
3337*cf2f2c56Smiod           sym->st_shndx = SHN_UNDEF;
3338*cf2f2c56Smiod         }
3339*cf2f2c56Smiod     }
3340*cf2f2c56Smiod 
3341*cf2f2c56Smiod   if (h->got.offset != (bfd_vma) -1)
3342*cf2f2c56Smiod     {
3343*cf2f2c56Smiod       asection *sgot;
3344*cf2f2c56Smiod       asection *srela;
3345*cf2f2c56Smiod       Elf_Internal_Rela rela;
3346*cf2f2c56Smiod 
3347*cf2f2c56Smiod       /* This symbol has an entry in the global offset table.  Set it
3348*cf2f2c56Smiod          up.  */
3349*cf2f2c56Smiod 
3350*cf2f2c56Smiod       sgot = htab->sgot;
3351*cf2f2c56Smiod       srela = htab->srelgot;
3352*cf2f2c56Smiod       BFD_ASSERT (sgot != NULL && srela != NULL);
3353*cf2f2c56Smiod 
3354*cf2f2c56Smiod       rela.r_offset = (sgot->output_section->vma
3355*cf2f2c56Smiod                        + sgot->output_offset
3356*cf2f2c56Smiod                        + (h->got.offset &~ 1));
3357*cf2f2c56Smiod 
3358*cf2f2c56Smiod       /* If this is a -Bsymbolic link, and the symbol is defined
3359*cf2f2c56Smiod          locally, we just want to emit a RELATIVE reloc.  Likewise if
3360*cf2f2c56Smiod          the symbol was forced to be local because of a version file.
3361*cf2f2c56Smiod          The entry in the global offset table will already have been
3362*cf2f2c56Smiod          initialized in the relocate_section function.  */
3363*cf2f2c56Smiod       if (info->shared
3364*cf2f2c56Smiod           && (info->symbolic
3365*cf2f2c56Smiod 	      || h->dynindx == -1
3366*cf2f2c56Smiod 	      || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
3367*cf2f2c56Smiod           && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
3368*cf2f2c56Smiod         {
3369*cf2f2c56Smiod           rela.r_info = ELF32_R_INFO (0, R_M32R_RELATIVE);
3370*cf2f2c56Smiod           rela.r_addend = (h->root.u.def.value
3371*cf2f2c56Smiod                            + h->root.u.def.section->output_section->vma
3372*cf2f2c56Smiod                            + h->root.u.def.section->output_offset);
3373*cf2f2c56Smiod         }
3374*cf2f2c56Smiod       else
3375*cf2f2c56Smiod         {
3376*cf2f2c56Smiod 	  BFD_ASSERT((h->got.offset & 1) == 0);
3377*cf2f2c56Smiod           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
3378*cf2f2c56Smiod           rela.r_info = ELF32_R_INFO (h->dynindx, R_M32R_GLOB_DAT);
3379*cf2f2c56Smiod           rela.r_addend = 0;
3380*cf2f2c56Smiod         }
3381*cf2f2c56Smiod 
3382*cf2f2c56Smiod       loc = srela->contents;
3383*cf2f2c56Smiod       loc += srela->reloc_count * sizeof(Elf32_External_Rela);
3384*cf2f2c56Smiod       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3385*cf2f2c56Smiod       ++srela->reloc_count;
3386*cf2f2c56Smiod     }
3387*cf2f2c56Smiod 
3388*cf2f2c56Smiod   if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
3389*cf2f2c56Smiod     {
3390*cf2f2c56Smiod       asection *s;
3391*cf2f2c56Smiod       Elf_Internal_Rela rela;
3392*cf2f2c56Smiod 
3393*cf2f2c56Smiod       /* This symbols needs a copy reloc.  Set it up.  */
3394*cf2f2c56Smiod 
3395*cf2f2c56Smiod       BFD_ASSERT (h->dynindx != -1
3396*cf2f2c56Smiod                   && (h->root.type == bfd_link_hash_defined
3397*cf2f2c56Smiod                       || h->root.type == bfd_link_hash_defweak));
3398*cf2f2c56Smiod 
3399*cf2f2c56Smiod       s = bfd_get_section_by_name (h->root.u.def.section->owner,
3400*cf2f2c56Smiod                                    ".rela.bss");
3401*cf2f2c56Smiod       BFD_ASSERT (s != NULL);
3402*cf2f2c56Smiod 
3403*cf2f2c56Smiod       rela.r_offset = (h->root.u.def.value
3404*cf2f2c56Smiod                        + h->root.u.def.section->output_section->vma
3405*cf2f2c56Smiod                        + h->root.u.def.section->output_offset);
3406*cf2f2c56Smiod       rela.r_info = ELF32_R_INFO (h->dynindx, R_M32R_COPY);
3407*cf2f2c56Smiod       rela.r_addend = 0;
3408*cf2f2c56Smiod       loc = s->contents;
3409*cf2f2c56Smiod       loc += s->reloc_count * sizeof(Elf32_External_Rela);
3410*cf2f2c56Smiod       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3411*cf2f2c56Smiod       ++s->reloc_count;
3412*cf2f2c56Smiod     }
3413*cf2f2c56Smiod 
3414*cf2f2c56Smiod   /* Mark some specially defined symbols as absolute.  */
3415*cf2f2c56Smiod   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
3416*cf2f2c56Smiod       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
3417*cf2f2c56Smiod     sym->st_shndx = SHN_ABS;
3418*cf2f2c56Smiod 
3419*cf2f2c56Smiod   return TRUE;
3420*cf2f2c56Smiod }
3421*cf2f2c56Smiod 
3422*cf2f2c56Smiod 
3423*cf2f2c56Smiod /* Finish up the dynamic sections.  */
3424*cf2f2c56Smiod 
3425*cf2f2c56Smiod static bfd_boolean
m32r_elf_finish_dynamic_sections(output_bfd,info)3426*cf2f2c56Smiod m32r_elf_finish_dynamic_sections (output_bfd, info)
3427*cf2f2c56Smiod      bfd *output_bfd;
3428*cf2f2c56Smiod      struct bfd_link_info *info;
3429*cf2f2c56Smiod {
3430*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
3431*cf2f2c56Smiod   bfd *dynobj;
3432*cf2f2c56Smiod   asection *sdyn;
3433*cf2f2c56Smiod   asection *sgot;
3434*cf2f2c56Smiod 
3435*cf2f2c56Smiod #ifdef DEBUG_PIC
3436*cf2f2c56Smiod printf("m32r_elf_finish_dynamic_sections()\n");
3437*cf2f2c56Smiod #endif
3438*cf2f2c56Smiod 
3439*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
3440*cf2f2c56Smiod   dynobj = htab->root.dynobj;
3441*cf2f2c56Smiod 
3442*cf2f2c56Smiod   sgot = htab->sgotplt;
3443*cf2f2c56Smiod   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3444*cf2f2c56Smiod 
3445*cf2f2c56Smiod   if (htab->root.dynamic_sections_created)
3446*cf2f2c56Smiod     {
3447*cf2f2c56Smiod       asection *splt;
3448*cf2f2c56Smiod       Elf32_External_Dyn *dyncon, *dynconend;
3449*cf2f2c56Smiod 
3450*cf2f2c56Smiod       BFD_ASSERT (sgot != NULL && sdyn != NULL);
3451*cf2f2c56Smiod 
3452*cf2f2c56Smiod       dyncon = (Elf32_External_Dyn *) sdyn->contents;
3453*cf2f2c56Smiod       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
3454*cf2f2c56Smiod 
3455*cf2f2c56Smiod       for (; dyncon < dynconend; dyncon++)
3456*cf2f2c56Smiod         {
3457*cf2f2c56Smiod           Elf_Internal_Dyn dyn;
3458*cf2f2c56Smiod           const char *name;
3459*cf2f2c56Smiod           asection *s;
3460*cf2f2c56Smiod 
3461*cf2f2c56Smiod           bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3462*cf2f2c56Smiod 
3463*cf2f2c56Smiod           switch (dyn.d_tag)
3464*cf2f2c56Smiod             {
3465*cf2f2c56Smiod             default:
3466*cf2f2c56Smiod               break;
3467*cf2f2c56Smiod 
3468*cf2f2c56Smiod             case DT_PLTGOT:
3469*cf2f2c56Smiod               name = ".got";
3470*cf2f2c56Smiod               s = htab->sgot->output_section;
3471*cf2f2c56Smiod               goto get_vma;
3472*cf2f2c56Smiod             case DT_JMPREL:
3473*cf2f2c56Smiod               name = ".rela.plt";
3474*cf2f2c56Smiod               s = htab->srelplt->output_section;
3475*cf2f2c56Smiod             get_vma:
3476*cf2f2c56Smiod               BFD_ASSERT (s != NULL);
3477*cf2f2c56Smiod               dyn.d_un.d_ptr = s->vma;
3478*cf2f2c56Smiod               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3479*cf2f2c56Smiod               break;
3480*cf2f2c56Smiod 
3481*cf2f2c56Smiod             case DT_PLTRELSZ:
3482*cf2f2c56Smiod               s = htab->srelplt->output_section;
3483*cf2f2c56Smiod               BFD_ASSERT (s != NULL);
3484*cf2f2c56Smiod               if (s->_cooked_size != 0)
3485*cf2f2c56Smiod                 dyn.d_un.d_val = s->_cooked_size;
3486*cf2f2c56Smiod               else
3487*cf2f2c56Smiod                 dyn.d_un.d_val = s->_raw_size;
3488*cf2f2c56Smiod               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3489*cf2f2c56Smiod               break;
3490*cf2f2c56Smiod 
3491*cf2f2c56Smiod             case DT_RELASZ:
3492*cf2f2c56Smiod               /* My reading of the SVR4 ABI indicates that the
3493*cf2f2c56Smiod                  procedure linkage table relocs (DT_JMPREL) should be
3494*cf2f2c56Smiod                  included in the overall relocs (DT_RELA).  This is
3495*cf2f2c56Smiod                  what Solaris does.  However, UnixWare can not handle
3496*cf2f2c56Smiod                  that case.  Therefore, we override the DT_RELASZ entry
3497*cf2f2c56Smiod                  here to make it not include the JMPREL relocs.  Since
3498*cf2f2c56Smiod                  the linker script arranges for .rela.plt to follow all
3499*cf2f2c56Smiod                  other relocation sections, we don't have to worry
3500*cf2f2c56Smiod                  about changing the DT_RELA entry.  */
3501*cf2f2c56Smiod               if (htab->srelplt != NULL)
3502*cf2f2c56Smiod                 {
3503*cf2f2c56Smiod                   s = htab->srelplt->output_section;
3504*cf2f2c56Smiod                   if (s->_cooked_size != 0)
3505*cf2f2c56Smiod                     dyn.d_un.d_val -= s->_cooked_size;
3506*cf2f2c56Smiod                   else
3507*cf2f2c56Smiod                     dyn.d_un.d_val -= s->_raw_size;
3508*cf2f2c56Smiod                 }
3509*cf2f2c56Smiod               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3510*cf2f2c56Smiod               break;
3511*cf2f2c56Smiod             }
3512*cf2f2c56Smiod         }
3513*cf2f2c56Smiod 
3514*cf2f2c56Smiod       /* Fill in the first entry in the procedure linkage table.  */
3515*cf2f2c56Smiod       splt = htab->splt;
3516*cf2f2c56Smiod       if (splt && splt->_raw_size > 0)
3517*cf2f2c56Smiod         {
3518*cf2f2c56Smiod           if (info->shared)
3519*cf2f2c56Smiod             {
3520*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0, splt->contents);
3521*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1, splt->contents + 4);
3522*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2, splt->contents + 8);
3523*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3, splt->contents + 12);
3524*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4, splt->contents + 16);
3525*cf2f2c56Smiod             }
3526*cf2f2c56Smiod           else
3527*cf2f2c56Smiod             {
3528*cf2f2c56Smiod               unsigned long addr;
3529*cf2f2c56Smiod               /* addr = .got + 4 */
3530*cf2f2c56Smiod               addr = sgot->output_section->vma + sgot->output_offset + 4;
3531*cf2f2c56Smiod               bfd_put_32 (output_bfd,
3532*cf2f2c56Smiod 			  PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff),
3533*cf2f2c56Smiod 			  splt->contents);
3534*cf2f2c56Smiod               bfd_put_32 (output_bfd,
3535*cf2f2c56Smiod 			  PLT0_ENTRY_WORD1 | (addr & 0xffff),
3536*cf2f2c56Smiod 			  splt->contents + 4);
3537*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8);
3538*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12);
3539*cf2f2c56Smiod               bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16);
3540*cf2f2c56Smiod             }
3541*cf2f2c56Smiod 
3542*cf2f2c56Smiod           elf_section_data (splt->output_section)->this_hdr.sh_entsize =
3543*cf2f2c56Smiod             PLT_ENTRY_SIZE;
3544*cf2f2c56Smiod         }
3545*cf2f2c56Smiod     }
3546*cf2f2c56Smiod 
3547*cf2f2c56Smiod   /* Fill in the first three entries in the global offset table.  */
3548*cf2f2c56Smiod   if (sgot && sgot->_raw_size > 0)
3549*cf2f2c56Smiod     {
3550*cf2f2c56Smiod       if (sdyn == NULL)
3551*cf2f2c56Smiod         bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3552*cf2f2c56Smiod       else
3553*cf2f2c56Smiod         bfd_put_32 (output_bfd,
3554*cf2f2c56Smiod                     sdyn->output_section->vma + sdyn->output_offset,
3555*cf2f2c56Smiod                     sgot->contents);
3556*cf2f2c56Smiod       bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
3557*cf2f2c56Smiod       bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
3558*cf2f2c56Smiod 
3559*cf2f2c56Smiod       elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3560*cf2f2c56Smiod     }
3561*cf2f2c56Smiod 
3562*cf2f2c56Smiod   return TRUE;
3563*cf2f2c56Smiod }
3564*cf2f2c56Smiod 
3565fddef416Sniklas 
3566fddef416Sniklas #if 0 /* relaxing not supported yet */
3567fddef416Sniklas 
3568fddef416Sniklas /* This function handles relaxing for the m32r.
3569fddef416Sniklas    Relaxing on the m32r is tricky because of instruction alignment
3570fddef416Sniklas    requirements (4 byte instructions must be aligned on 4 byte boundaries).
3571fddef416Sniklas 
3572fddef416Sniklas    The following relaxing opportunities are handled:
3573fddef416Sniklas 
3574fddef416Sniklas    seth/add3/jl -> bl24 or bl8
3575fddef416Sniklas    seth/add3 -> ld24
3576fddef416Sniklas 
3577fddef416Sniklas    It would be nice to handle bl24 -> bl8 but given:
3578fddef416Sniklas 
3579fddef416Sniklas    - 4 byte insns must be on 4 byte boundaries
3580fddef416Sniklas    - branch instructions only branch to insns on 4 byte boundaries
3581fddef416Sniklas 
3582fddef416Sniklas    this isn't much of a win because the insn in the 2 "deleted" bytes
3583fddef416Sniklas    must become a nop.  With some complexity some real relaxation could be
3584fddef416Sniklas    done but the frequency just wouldn't make it worth it; it's better to
3585fddef416Sniklas    try to do all the code compaction one can elsewhere.
3586fddef416Sniklas    When the chip supports parallel 16 bit insns, things may change.
3587fddef416Sniklas */
3588fddef416Sniklas 
3589d2201f2fSdrahn static bfd_boolean
3590fddef416Sniklas m32r_elf_relax_section (abfd, sec, link_info, again)
3591fddef416Sniklas      bfd *abfd;
3592fddef416Sniklas      asection *sec;
3593fddef416Sniklas      struct bfd_link_info *link_info;
3594d2201f2fSdrahn      bfd_boolean *again;
3595fddef416Sniklas {
3596fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
3597fddef416Sniklas   /* The Rela structures are used here because that's what
3598*cf2f2c56Smiod      _bfd_elf_link_read_relocs uses [for convenience - it sets the addend
3599fddef416Sniklas      field to 0].  */
3600d2201f2fSdrahn   Elf_Internal_Rela *internal_relocs = NULL;
3601fddef416Sniklas   Elf_Internal_Rela *irel, *irelend;
3602fddef416Sniklas   bfd_byte *contents = NULL;
3603d2201f2fSdrahn   Elf_Internal_Sym *isymbuf = NULL;
3604fddef416Sniklas 
3605fddef416Sniklas   /* Assume nothing changes.  */
3606d2201f2fSdrahn   *again = FALSE;
3607fddef416Sniklas 
3608*cf2f2c56Smiod   /* We don't have to do anything for a relocatable link, if
3609fddef416Sniklas      this section does not have relocs, or if this is not a
3610fddef416Sniklas      code section.  */
3611*cf2f2c56Smiod   if (link_info->relocatable
3612fddef416Sniklas       || (sec->flags & SEC_RELOC) == 0
3613fddef416Sniklas       || sec->reloc_count == 0
3614fddef416Sniklas       || (sec->flags & SEC_CODE) == 0
3615fddef416Sniklas       || 0 /* FIXME: check SHF_M32R_CAN_RELAX */)
3616d2201f2fSdrahn     return TRUE;
3617fddef416Sniklas 
3618fddef416Sniklas   /* If this is the first time we have been called for this section,
3619fddef416Sniklas      initialize the cooked size.  */
3620fddef416Sniklas   if (sec->_cooked_size == 0)
3621fddef416Sniklas     sec->_cooked_size = sec->_raw_size;
3622fddef416Sniklas 
3623fddef416Sniklas   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3624fddef416Sniklas 
3625fddef416Sniklas   /* Get a copy of the native relocations.  */
3626*cf2f2c56Smiod   internal_relocs = (_bfd_elf_link_read_relocs
3627fddef416Sniklas 		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
3628fddef416Sniklas 		      link_info->keep_memory));
3629fddef416Sniklas   if (internal_relocs == NULL)
3630fddef416Sniklas     goto error_return;
3631fddef416Sniklas 
3632fddef416Sniklas   /* Walk through them looking for relaxing opportunities.  */
3633fddef416Sniklas   irelend = internal_relocs + sec->reloc_count;
3634fddef416Sniklas   for (irel = internal_relocs; irel < irelend; irel++)
3635fddef416Sniklas     {
3636fddef416Sniklas       bfd_vma symval;
3637fddef416Sniklas 
3638fddef416Sniklas       /* If this isn't something that can be relaxed, then ignore
3639fddef416Sniklas 	 this reloc.  */
3640fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) != (int) R_M32R_HI16_SLO)
3641fddef416Sniklas 	continue;
3642fddef416Sniklas 
3643fddef416Sniklas       /* Get the section contents if we haven't done so already.  */
3644fddef416Sniklas       if (contents == NULL)
3645fddef416Sniklas 	{
3646fddef416Sniklas 	  /* Get cached copy if it exists.  */
3647fddef416Sniklas 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
3648fddef416Sniklas 	    contents = elf_section_data (sec)->this_hdr.contents;
3649fddef416Sniklas 	  else
3650fddef416Sniklas 	    {
3651fddef416Sniklas 	      /* Go get them off disk.  */
3652fddef416Sniklas 	      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
3653fddef416Sniklas 	      if (contents == NULL)
3654fddef416Sniklas 		goto error_return;
3655fddef416Sniklas 
3656fddef416Sniklas 	      if (! bfd_get_section_contents (abfd, sec, contents,
3657fddef416Sniklas 					      (file_ptr) 0, sec->_raw_size))
3658fddef416Sniklas 		goto error_return;
3659fddef416Sniklas 	    }
3660fddef416Sniklas 	}
3661fddef416Sniklas 
3662d2201f2fSdrahn       /* Read this BFD's local symbols if we haven't done so already.  */
3663d2201f2fSdrahn       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
3664fddef416Sniklas 	{
3665d2201f2fSdrahn 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3666d2201f2fSdrahn 	  if (isymbuf == NULL)
3667d2201f2fSdrahn 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3668d2201f2fSdrahn 					    symtab_hdr->sh_info, 0,
3669d2201f2fSdrahn 					    NULL, NULL, NULL);
3670d2201f2fSdrahn 	  if (isymbuf == NULL)
3671fddef416Sniklas 	    goto error_return;
3672fddef416Sniklas 	}
3673fddef416Sniklas 
3674fddef416Sniklas       /* Get the value of the symbol referred to by the reloc.  */
3675fddef416Sniklas       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
3676fddef416Sniklas 	{
3677d2201f2fSdrahn 	  /* A local symbol.  */
3678d2201f2fSdrahn 	  Elf_Internal_Sym *isym;
3679fddef416Sniklas 	  asection *sym_sec;
3680fddef416Sniklas 
3681d2201f2fSdrahn 	  isym = isymbuf + ELF32_R_SYM (irel->r_info),
3682d2201f2fSdrahn 	  sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3683d2201f2fSdrahn 	  symval = (isym->st_value
3684fddef416Sniklas 		    + sym_sec->output_section->vma
3685fddef416Sniklas 		    + sym_sec->output_offset);
3686fddef416Sniklas 	}
3687fddef416Sniklas       else
3688fddef416Sniklas 	{
3689fddef416Sniklas 	  unsigned long indx;
3690fddef416Sniklas 	  struct elf_link_hash_entry *h;
3691fddef416Sniklas 
3692fddef416Sniklas 	  /* An external symbol.  */
3693fddef416Sniklas 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3694fddef416Sniklas 	  h = elf_sym_hashes (abfd)[indx];
3695fddef416Sniklas 	  BFD_ASSERT (h != NULL);
3696fddef416Sniklas 	  if (h->root.type != bfd_link_hash_defined
3697fddef416Sniklas 	      && h->root.type != bfd_link_hash_defweak)
3698fddef416Sniklas 	    {
3699fddef416Sniklas 	      /* This appears to be a reference to an undefined
3700fddef416Sniklas                  symbol.  Just ignore it--it will be caught by the
3701fddef416Sniklas                  regular reloc processing.  */
3702fddef416Sniklas 	      continue;
3703fddef416Sniklas 	    }
3704fddef416Sniklas 
3705fddef416Sniklas 	  symval = (h->root.u.def.value
3706fddef416Sniklas 		    + h->root.u.def.section->output_section->vma
3707fddef416Sniklas 		    + h->root.u.def.section->output_offset);
3708fddef416Sniklas 	}
3709fddef416Sniklas 
3710fddef416Sniklas       /* For simplicity of coding, we are going to modify the section
3711fddef416Sniklas 	 contents, the section relocs, and the BFD symbol table.  We
3712fddef416Sniklas 	 must tell the rest of the code not to free up this
3713fddef416Sniklas 	 information.  It would be possible to instead create a table
3714fddef416Sniklas 	 of changes which have to be made, as is done in coff-mips.c;
3715fddef416Sniklas 	 that would be more work, but would require less memory when
3716fddef416Sniklas 	 the linker is run.  */
3717fddef416Sniklas 
3718fddef416Sniklas       /* Try to change a seth/add3/jl subroutine call to bl24 or bl8.
3719fddef416Sniklas 	 This sequence is generated by the compiler when compiling in
3720fddef416Sniklas 	 32 bit mode.  Also look for seth/add3 -> ld24.  */
3721fddef416Sniklas 
3722fddef416Sniklas       if (ELF32_R_TYPE (irel->r_info) == (int) R_M32R_HI16_SLO)
3723fddef416Sniklas 	{
3724fddef416Sniklas 	  Elf_Internal_Rela *nrel;
3725fddef416Sniklas 	  bfd_vma pc = (sec->output_section->vma + sec->output_offset
3726fddef416Sniklas 			+ irel->r_offset);
3727fddef416Sniklas 	  bfd_signed_vma pcrel_value = symval - pc;
3728fddef416Sniklas 	  unsigned int code,reg;
3729fddef416Sniklas 	  int addend,nop_p,bl8_p,to_delete;
3730fddef416Sniklas 
3731fddef416Sniklas 	  /* The tests are ordered so that we get out as quickly as possible
3732fddef416Sniklas 	     if this isn't something we can relax, taking into account that
3733fddef416Sniklas 	     we are looking for two separate possibilities (jl/ld24).  */
3734fddef416Sniklas 
3735fddef416Sniklas 	  /* Do nothing if no room in the section for this to be what we're
3736fddef416Sniklas 	     looking for.  */
3737fddef416Sniklas 	  if (irel->r_offset > sec->_cooked_size - 8)
3738fddef416Sniklas 	    continue;
3739fddef416Sniklas 
3740fddef416Sniklas 	  /* Make sure the next relocation applies to the next
3741fddef416Sniklas 	     instruction and that it's the add3's reloc.  */
3742fddef416Sniklas 	  nrel = irel + 1;
3743fddef416Sniklas 	  if (nrel == irelend
3744fddef416Sniklas 	      || irel->r_offset + 4 != nrel->r_offset
3745fddef416Sniklas 	      || ELF32_R_TYPE (nrel->r_info) != (int) R_M32R_LO16)
3746fddef416Sniklas 	    continue;
3747fddef416Sniklas 
3748fddef416Sniklas 	  /* See if the instructions are seth/add3.  */
3749fddef416Sniklas 	  /* FIXME: This is where macros from cgen can come in.  */
3750fddef416Sniklas 	  code = bfd_get_16 (abfd, contents + irel->r_offset + 0);
3751fddef416Sniklas 	  if ((code & 0xf0ff) != 0xd0c0)
3752fddef416Sniklas 	    continue; /* not seth rN,foo */
3753fddef416Sniklas 	  reg = (code & 0x0f00) >> 8;
3754fddef416Sniklas 	  code = bfd_get_16 (abfd, contents + irel->r_offset + 4);
3755fddef416Sniklas 	  if (code != (0x80a0 | reg | (reg << 8)))
3756fddef416Sniklas 	    continue; /* not add3 rN,rN,foo */
3757fddef416Sniklas 
3758fddef416Sniklas 	  /* At this point we've confirmed we have seth/add3.  Now check
3759fddef416Sniklas 	     whether the next insn is a jl, in which case try to change this
3760fddef416Sniklas 	     to bl24 or bl8.  */
3761fddef416Sniklas 
3762fddef416Sniklas 	  /* Ensure the branch target is in range.
3763fddef416Sniklas 	     The bl24 instruction has a 24 bit operand which is the target
3764fddef416Sniklas 	     address right shifted by 2, giving a signed range of 26 bits.
3765fddef416Sniklas 	     Note that 4 bytes are added to the high value because the target
3766fddef416Sniklas 	     will be at least 4 bytes closer if we can relax.  It'll actually
3767fddef416Sniklas 	     be 4 or 8 bytes closer, but we don't know which just yet and
3768fddef416Sniklas 	     the difference isn't significant enough to worry about.  */
3769d2201f2fSdrahn #if !USE_REL /* put in for learning purposes */
3770fddef416Sniklas 	  pcrel_value += irel->r_addend;
3771fddef416Sniklas #else
3772fddef416Sniklas 	  addend = bfd_get_signed_16 (abfd, contents + irel->r_offset + 2);
3773fddef416Sniklas 	  pcrel_value += addend;
3774fddef416Sniklas #endif
3775fddef416Sniklas 
3776fddef416Sniklas 	  if (pcrel_value >= -(1 << 25) && pcrel_value < (1 << 25) + 4
3777fddef416Sniklas 	      /* Do nothing if no room in the section for this to be what we're
3778fddef416Sniklas 		 looking for.  */
3779fddef416Sniklas 	      && (irel->r_offset <= sec->_cooked_size - 12)
3780fddef416Sniklas 	      /* Ensure the next insn is "jl rN".  */
3781fddef416Sniklas 	      && ((code = bfd_get_16 (abfd, contents + irel->r_offset + 8)),
3782fddef416Sniklas 		  code != (0x1ec0 | reg)))
3783fddef416Sniklas 	    {
3784fddef416Sniklas 	      /* We can relax to bl24/bl8.  */
3785fddef416Sniklas 
3786fddef416Sniklas 	      /* See if there's a nop following the jl.
3787fddef416Sniklas 		 Also see if we can use a bl8 insn.  */
3788fddef416Sniklas 	      code = bfd_get_16 (abfd, contents + irel->r_offset + 10);
3789f7cc78ecSespie 	      nop_p = (code & 0x7fff) == NOP_INSN;
3790fddef416Sniklas 	      bl8_p = pcrel_value >= -0x200 && pcrel_value < 0x200;
3791fddef416Sniklas 
3792fddef416Sniklas 	      if (bl8_p)
3793fddef416Sniklas 		{
3794fddef416Sniklas 		  /* Change "seth rN,foo" to "bl8 foo || nop".
3795fddef416Sniklas 		     We OR in CODE just in case it's not a nop (technically,
3796fddef416Sniklas 		     CODE currently must be a nop, but for cleanness we
3797fddef416Sniklas 		     allow it to be anything).  */
3798d2201f2fSdrahn #if !USE_REL /* put in for learning purposes */
3799f7cc78ecSespie 		  code = 0x7e000000 | MAKE_PARALLEL (code);
3800fddef416Sniklas #else
3801f7cc78ecSespie 		  code = (0x7e000000 + (((addend >> 2) & 0xff) << 16)) | MAKE_PARALLEL (code);
3802fddef416Sniklas #endif
3803fddef416Sniklas 		  to_delete = 8;
3804fddef416Sniklas 		}
3805fddef416Sniklas 	      else
3806fddef416Sniklas 		{
3807fddef416Sniklas 		  /* Change the seth rN,foo to a bl24 foo.  */
3808d2201f2fSdrahn #if !USE_REL /* put in for learning purposes */
3809fddef416Sniklas 		  code = 0xfe000000;
3810fddef416Sniklas #else
3811fddef416Sniklas 		  code = 0xfe000000 + ((addend >> 2) & 0xffffff);
3812fddef416Sniklas #endif
3813fddef416Sniklas 		  to_delete = nop_p ? 8 : 4;
3814fddef416Sniklas 		}
3815fddef416Sniklas 
3816fddef416Sniklas 	      bfd_put_32 (abfd, code, contents + irel->r_offset);
3817fddef416Sniklas 
3818fddef416Sniklas 	      /* Set the new reloc type.  */
3819fddef416Sniklas 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
3820fddef416Sniklas 					   bl8_p ? R_M32R_10_PCREL : R_M32R_26_PCREL);
3821fddef416Sniklas 
3822fddef416Sniklas 	      /* Delete the add3 reloc by making it a null reloc.  */
3823fddef416Sniklas 	      nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
3824fddef416Sniklas 					   R_M32R_NONE);
3825fddef416Sniklas 	    }
3826fddef416Sniklas 	  else if (addend >= 0
3827fddef416Sniklas 		   && symval + addend <= 0xffffff)
3828fddef416Sniklas 	    {
3829fddef416Sniklas 	      /* We can relax to ld24.  */
3830fddef416Sniklas 
3831fddef416Sniklas 	      code = 0xe0000000 | (reg << 24) | (addend & 0xffffff);
3832fddef416Sniklas 	      bfd_put_32 (abfd, code, contents + irel->r_offset);
3833fddef416Sniklas 	      to_delete = 4;
3834fddef416Sniklas 	      /* Tell the following code a nop filler isn't needed.  */
3835fddef416Sniklas 	      nop_p = 1;
3836fddef416Sniklas 	    }
3837fddef416Sniklas 	  else
3838fddef416Sniklas 	    {
3839fddef416Sniklas 	      /* Can't do anything here.  */
3840fddef416Sniklas 	      continue;
3841fddef416Sniklas 	    }
3842fddef416Sniklas 
3843fddef416Sniklas 	  /* Note that we've changed the relocs, section contents, etc.  */
3844fddef416Sniklas 	  elf_section_data (sec)->relocs = internal_relocs;
3845fddef416Sniklas 	  elf_section_data (sec)->this_hdr.contents = contents;
3846d2201f2fSdrahn 	  symtab_hdr->contents = (unsigned char *) isymbuf;
3847fddef416Sniklas 
3848fddef416Sniklas 	  /* Delete TO_DELETE bytes of data.  */
3849fddef416Sniklas 	  if (!m32r_elf_relax_delete_bytes (abfd, sec,
3850fddef416Sniklas 					    irel->r_offset + 4, to_delete))
3851fddef416Sniklas 	    goto error_return;
3852fddef416Sniklas 
3853fddef416Sniklas 	  /* Now that the following bytes have been moved into place, see if
3854fddef416Sniklas 	     we need to replace the jl with a nop.  This happens when we had
3855fddef416Sniklas 	     to use a bl24 insn and the insn following the jl isn't a nop.
3856fddef416Sniklas 	     Technically, this situation can't happen (since the insn can
3857fddef416Sniklas 	     never be executed) but to be clean we do this.  When the chip
3858fddef416Sniklas 	     supports parallel 16 bit insns things may change.
3859fddef416Sniklas 	     We don't need to do this in the case of relaxing to ld24,
3860fddef416Sniklas 	     and the above code sets nop_p so this isn't done.  */
3861fddef416Sniklas 	  if (! nop_p && to_delete == 4)
3862f7cc78ecSespie 	    bfd_put_16 (abfd, NOP_INSN, contents + irel->r_offset + 4);
3863fddef416Sniklas 
3864fddef416Sniklas 	  /* That will change things, so we should relax again.
3865fddef416Sniklas 	     Note that this is not required, and it may be slow.  */
3866d2201f2fSdrahn 	  *again = TRUE;
3867fddef416Sniklas 
3868fddef416Sniklas 	  continue;
3869fddef416Sniklas 	}
3870fddef416Sniklas 
3871fddef416Sniklas       /* loop to try the next reloc */
3872fddef416Sniklas     }
3873fddef416Sniklas 
3874d2201f2fSdrahn   if (isymbuf != NULL
3875d2201f2fSdrahn       && symtab_hdr->contents != (unsigned char *) isymbuf)
3876fddef416Sniklas     {
3877fddef416Sniklas       if (! link_info->keep_memory)
3878d2201f2fSdrahn 	free (isymbuf);
3879d2201f2fSdrahn       else
3880d2201f2fSdrahn 	{
3881d2201f2fSdrahn 	  /* Cache the symbols for elf_link_input_bfd.  */
3882d2201f2fSdrahn 	  symtab_hdr->contents = (unsigned char *) isymbuf;
3883d2201f2fSdrahn 	}
3884d2201f2fSdrahn     }
3885d2201f2fSdrahn 
3886d2201f2fSdrahn   if (contents != NULL
3887d2201f2fSdrahn       && elf_section_data (sec)->this_hdr.contents != contents)
3888d2201f2fSdrahn     {
3889d2201f2fSdrahn       if (! link_info->keep_memory)
3890d2201f2fSdrahn 	free (contents);
3891fddef416Sniklas       else
3892fddef416Sniklas 	{
3893fddef416Sniklas 	  /* Cache the section contents for elf_link_input_bfd.  */
3894fddef416Sniklas 	  elf_section_data (sec)->this_hdr.contents = contents;
3895fddef416Sniklas 	}
3896fddef416Sniklas     }
3897fddef416Sniklas 
3898d2201f2fSdrahn   if (internal_relocs != NULL
3899d2201f2fSdrahn       && elf_section_data (sec)->relocs != internal_relocs)
3900d2201f2fSdrahn     free (internal_relocs);
3901fddef416Sniklas 
3902d2201f2fSdrahn   return TRUE;
3903fddef416Sniklas 
3904fddef416Sniklas  error_return:
3905d2201f2fSdrahn   if (isymbuf != NULL
3906d2201f2fSdrahn       && symtab_hdr->contents != (unsigned char *) isymbuf)
3907d2201f2fSdrahn     free (isymbuf);
3908d2201f2fSdrahn   if (contents != NULL
3909d2201f2fSdrahn       && elf_section_data (sec)->this_hdr.contents != contents)
3910d2201f2fSdrahn     free (contents);
3911d2201f2fSdrahn   if (internal_relocs != NULL
3912d2201f2fSdrahn       && elf_section_data (sec)->relocs != internal_relocs)
3913d2201f2fSdrahn     free (internal_relocs);
3914d2201f2fSdrahn 
3915d2201f2fSdrahn   return FALSE;
3916fddef416Sniklas }
3917fddef416Sniklas 
3918fddef416Sniklas /* Delete some bytes from a section while relaxing.  */
3919fddef416Sniklas 
3920d2201f2fSdrahn static bfd_boolean
3921fddef416Sniklas m32r_elf_relax_delete_bytes (abfd, sec, addr, count)
3922fddef416Sniklas      bfd *abfd;
3923fddef416Sniklas      asection *sec;
3924fddef416Sniklas      bfd_vma addr;
3925fddef416Sniklas      int count;
3926fddef416Sniklas {
3927fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
3928d2201f2fSdrahn   int shndx;
3929fddef416Sniklas   bfd_byte *contents;
3930fddef416Sniklas   Elf_Internal_Rela *irel, *irelend;
3931fddef416Sniklas   Elf_Internal_Rela *irelalign;
3932fddef416Sniklas   bfd_vma toaddr;
3933d2201f2fSdrahn   Elf_Internal_Sym *isym, *isymend;
3934d2201f2fSdrahn   struct elf_link_hash_entry **sym_hashes;
3935d2201f2fSdrahn   struct elf_link_hash_entry **end_hashes;
3936d2201f2fSdrahn   unsigned int symcount;
3937fddef416Sniklas 
3938fddef416Sniklas   shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
3939fddef416Sniklas 
3940fddef416Sniklas   contents = elf_section_data (sec)->this_hdr.contents;
3941fddef416Sniklas 
3942fddef416Sniklas   /* The deletion must stop at the next ALIGN reloc for an aligment
3943fddef416Sniklas      power larger than the number of bytes we are deleting.  */
3944fddef416Sniklas 
3945fddef416Sniklas   irelalign = NULL;
3946fddef416Sniklas   toaddr = sec->_cooked_size;
3947fddef416Sniklas 
3948fddef416Sniklas   irel = elf_section_data (sec)->relocs;
3949fddef416Sniklas   irelend = irel + sec->reloc_count;
3950fddef416Sniklas 
3951fddef416Sniklas   /* Actually delete the bytes.  */
3952fddef416Sniklas   memmove (contents + addr, contents + addr + count, toaddr - addr - count);
3953fddef416Sniklas   sec->_cooked_size -= count;
3954fddef416Sniklas 
3955fddef416Sniklas   /* Adjust all the relocs.  */
3956fddef416Sniklas   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
3957fddef416Sniklas     {
3958fddef416Sniklas       /* Get the new reloc address.  */
3959fddef416Sniklas       if ((irel->r_offset > addr
3960fddef416Sniklas 	   && irel->r_offset < toaddr))
3961fddef416Sniklas 	irel->r_offset -= count;
3962fddef416Sniklas     }
3963fddef416Sniklas 
3964f7cc78ecSespie   /* Adjust the local symbols defined in this section.  */
3965d2201f2fSdrahn   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3966d2201f2fSdrahn   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
3967d2201f2fSdrahn   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
3968fddef416Sniklas     {
3969d2201f2fSdrahn       if (isym->st_shndx == shndx
3970d2201f2fSdrahn 	  && isym->st_value > addr
3971d2201f2fSdrahn 	  && isym->st_value < toaddr)
3972d2201f2fSdrahn 	isym->st_value -= count;
3973fddef416Sniklas     }
3974fddef416Sniklas 
3975f7cc78ecSespie   /* Now adjust the global symbols defined in this section.  */
3976d2201f2fSdrahn   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
3977d2201f2fSdrahn 	      - symtab_hdr->sh_info);
3978d2201f2fSdrahn   sym_hashes = elf_sym_hashes (abfd);
3979d2201f2fSdrahn   end_hashes = sym_hashes + symcount;
3980d2201f2fSdrahn   for (; sym_hashes < end_hashes; sym_hashes++)
3981fddef416Sniklas     {
3982d2201f2fSdrahn       struct elf_link_hash_entry *sym_hash = *sym_hashes;
3983f7cc78ecSespie 
3984d2201f2fSdrahn       if ((sym_hash->root.type == bfd_link_hash_defined
3985d2201f2fSdrahn 	   || sym_hash->root.type == bfd_link_hash_defweak)
3986d2201f2fSdrahn 	  && sym_hash->root.u.def.section == sec
3987d2201f2fSdrahn 	  && sym_hash->root.u.def.value > addr
3988d2201f2fSdrahn 	  && sym_hash->root.u.def.value < toaddr)
3989fddef416Sniklas 	{
3990d2201f2fSdrahn 	  sym_hash->root.u.def.value -= count;
3991fddef416Sniklas 	}
3992fddef416Sniklas     }
3993fddef416Sniklas 
3994d2201f2fSdrahn   return TRUE;
3995fddef416Sniklas }
3996fddef416Sniklas 
3997fddef416Sniklas /* This is a version of bfd_generic_get_relocated_section_contents
3998fddef416Sniklas    which uses m32r_elf_relocate_section.  */
3999fddef416Sniklas 
4000fddef416Sniklas static bfd_byte *
4001fddef416Sniklas m32r_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
4002*cf2f2c56Smiod 					 data, relocatable, symbols)
4003fddef416Sniklas      bfd *output_bfd;
4004fddef416Sniklas      struct bfd_link_info *link_info;
4005fddef416Sniklas      struct bfd_link_order *link_order;
4006fddef416Sniklas      bfd_byte *data;
4007*cf2f2c56Smiod      bfd_boolean relocatable;
4008fddef416Sniklas      asymbol **symbols;
4009fddef416Sniklas {
4010fddef416Sniklas   Elf_Internal_Shdr *symtab_hdr;
4011fddef416Sniklas   asection *input_section = link_order->u.indirect.section;
4012fddef416Sniklas   bfd *input_bfd = input_section->owner;
4013fddef416Sniklas   asection **sections = NULL;
4014fddef416Sniklas   Elf_Internal_Rela *internal_relocs = NULL;
4015d2201f2fSdrahn   Elf_Internal_Sym *isymbuf = NULL;
4016d2201f2fSdrahn   bfd_size_type amt;
4017fddef416Sniklas 
4018fddef416Sniklas   /* We only need to handle the case of relaxing, or of having a
4019fddef416Sniklas      particular set of section contents, specially.  */
4020*cf2f2c56Smiod   if (relocatable
4021fddef416Sniklas       || elf_section_data (input_section)->this_hdr.contents == NULL)
4022fddef416Sniklas     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
4023fddef416Sniklas 						       link_order, data,
4024*cf2f2c56Smiod 						       relocatable,
4025fddef416Sniklas 						       symbols);
4026fddef416Sniklas 
4027fddef416Sniklas   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4028fddef416Sniklas 
4029fddef416Sniklas   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
4030fddef416Sniklas 	  input_section->_raw_size);
4031fddef416Sniklas 
4032fddef416Sniklas   if ((input_section->flags & SEC_RELOC) != 0
4033fddef416Sniklas       && input_section->reloc_count > 0)
4034fddef416Sniklas     {
4035fddef416Sniklas       Elf_Internal_Sym *isymp;
4036fddef416Sniklas       asection **secpp;
4037fddef416Sniklas       Elf32_External_Sym *esym, *esymend;
4038fddef416Sniklas 
4039*cf2f2c56Smiod       internal_relocs = (_bfd_elf_link_read_relocs
4040fddef416Sniklas 			 (input_bfd, input_section, (PTR) NULL,
4041d2201f2fSdrahn 			  (Elf_Internal_Rela *) NULL, FALSE));
4042fddef416Sniklas       if (internal_relocs == NULL)
4043fddef416Sniklas 	goto error_return;
4044fddef416Sniklas 
4045d2201f2fSdrahn       if (symtab_hdr->sh_info != 0)
4046d2201f2fSdrahn 	{
4047d2201f2fSdrahn 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
4048d2201f2fSdrahn 	  if (isymbuf == NULL)
4049d2201f2fSdrahn 	    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
4050d2201f2fSdrahn 					    symtab_hdr->sh_info, 0,
4051d2201f2fSdrahn 					    NULL, NULL, NULL);
4052d2201f2fSdrahn 	  if (isymbuf == NULL)
4053fddef416Sniklas 	    goto error_return;
4054d2201f2fSdrahn 	}
4055fddef416Sniklas 
4056d2201f2fSdrahn       amt = symtab_hdr->sh_info;
4057d2201f2fSdrahn       amt *= sizeof (asection *);
4058d2201f2fSdrahn       sections = (asection **) bfd_malloc (amt);
4059fddef416Sniklas       if (sections == NULL && symtab_hdr->sh_info > 0)
4060fddef416Sniklas 	goto error_return;
4061fddef416Sniklas 
4062d2201f2fSdrahn       isymend = isymbuf + symtab_hdr->sh_info;
4063d2201f2fSdrahn       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
4064fddef416Sniklas 	{
4065fddef416Sniklas 	  asection *isec;
4066fddef416Sniklas 
4067d2201f2fSdrahn 	  if (isym->st_shndx == SHN_UNDEF)
4068fddef416Sniklas 	    isec = bfd_und_section_ptr;
4069d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_ABS)
4070fddef416Sniklas 	    isec = bfd_abs_section_ptr;
4071d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_COMMON)
4072fddef416Sniklas 	    isec = bfd_com_section_ptr;
4073d2201f2fSdrahn 	  else if (isym->st_shndx == SHN_M32R_SCOMMON)
4074fddef416Sniklas 	    isec = &m32r_elf_scom_section;
4075fddef416Sniklas 	  else
4076d2201f2fSdrahn 	    isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
4077fddef416Sniklas 
4078fddef416Sniklas 	  *secpp = isec;
4079fddef416Sniklas 	}
4080fddef416Sniklas 
4081fddef416Sniklas       if (! m32r_elf_relocate_section (output_bfd, link_info, input_bfd,
4082fddef416Sniklas 				       input_section, data, internal_relocs,
4083d2201f2fSdrahn 				       isymbuf, sections))
4084fddef416Sniklas 	goto error_return;
4085fddef416Sniklas 
4086fddef416Sniklas       if (sections != NULL)
4087fddef416Sniklas 	free (sections);
4088d2201f2fSdrahn       if (isymbuf != NULL
4089d2201f2fSdrahn 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
4090d2201f2fSdrahn 	free (isymbuf);
4091d2201f2fSdrahn       if (elf_section_data (input_section)->relocs != internal_relocs)
4092fddef416Sniklas 	free (internal_relocs);
4093fddef416Sniklas     }
4094fddef416Sniklas 
4095fddef416Sniklas   return data;
4096fddef416Sniklas 
4097fddef416Sniklas  error_return:
4098fddef416Sniklas   if (sections != NULL)
4099fddef416Sniklas     free (sections);
4100d2201f2fSdrahn   if (isymbuf != NULL
4101d2201f2fSdrahn       && symtab_hdr->contents != (unsigned char *) isymbuf)
4102d2201f2fSdrahn     free (isymbuf);
4103d2201f2fSdrahn   if (internal_relocs != NULL
4104d2201f2fSdrahn       && elf_section_data (input_section)->relocs != internal_relocs)
4105d2201f2fSdrahn     free (internal_relocs);
4106fddef416Sniklas   return NULL;
4107fddef416Sniklas }
4108fddef416Sniklas 
4109fddef416Sniklas #endif /* #if 0 */
4110fddef416Sniklas 
4111f7cc78ecSespie /* Set the right machine number.  */
4112d2201f2fSdrahn static bfd_boolean
m32r_elf_object_p(abfd)4113f7cc78ecSespie m32r_elf_object_p (abfd)
4114f7cc78ecSespie      bfd *abfd;
4115f7cc78ecSespie {
4116f7cc78ecSespie   switch (elf_elfheader (abfd)->e_flags & EF_M32R_ARCH)
4117f7cc78ecSespie     {
4118f7cc78ecSespie     default:
4119f7cc78ecSespie     case E_M32R_ARCH:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_m32r, bfd_mach_m32r);  break;
4120f7cc78ecSespie     case E_M32RX_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_m32r, bfd_mach_m32rx); break;
4121*cf2f2c56Smiod     case E_M32R2_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_m32r, bfd_mach_m32r2); break;
4122f7cc78ecSespie     }
4123d2201f2fSdrahn   return TRUE;
4124f7cc78ecSespie }
4125f7cc78ecSespie 
4126f7cc78ecSespie /* Store the machine number in the flags field.  */
4127f7cc78ecSespie static void
m32r_elf_final_write_processing(abfd,linker)4128f7cc78ecSespie m32r_elf_final_write_processing (abfd, linker)
4129f7cc78ecSespie      bfd *abfd;
4130d2201f2fSdrahn      bfd_boolean linker ATTRIBUTE_UNUSED;
4131f7cc78ecSespie {
4132f7cc78ecSespie   unsigned long val;
4133f7cc78ecSespie 
4134f7cc78ecSespie   switch (bfd_get_mach (abfd))
4135f7cc78ecSespie     {
4136f7cc78ecSespie     default:
4137f7cc78ecSespie     case bfd_mach_m32r:  val = E_M32R_ARCH; break;
4138f7cc78ecSespie     case bfd_mach_m32rx: val = E_M32RX_ARCH; break;
4139*cf2f2c56Smiod     case bfd_mach_m32r2: val = E_M32R2_ARCH; break;
4140f7cc78ecSespie     }
4141f7cc78ecSespie 
4142f7cc78ecSespie   elf_elfheader (abfd)->e_flags &=~ EF_M32R_ARCH;
4143f7cc78ecSespie   elf_elfheader (abfd)->e_flags |= val;
4144f7cc78ecSespie }
4145f7cc78ecSespie 
4146f7cc78ecSespie /* Function to keep M32R specific file flags.  */
4147d2201f2fSdrahn static bfd_boolean
m32r_elf_set_private_flags(abfd,flags)4148f7cc78ecSespie m32r_elf_set_private_flags (abfd, flags)
4149f7cc78ecSespie      bfd *abfd;
4150f7cc78ecSespie      flagword flags;
4151f7cc78ecSespie {
4152f7cc78ecSespie   BFD_ASSERT (!elf_flags_init (abfd)
4153f7cc78ecSespie 	      || elf_elfheader (abfd)->e_flags == flags);
4154f7cc78ecSespie 
4155f7cc78ecSespie   elf_elfheader (abfd)->e_flags = flags;
4156d2201f2fSdrahn   elf_flags_init (abfd) = TRUE;
4157d2201f2fSdrahn   return TRUE;
4158f7cc78ecSespie }
4159f7cc78ecSespie 
4160f7cc78ecSespie /* Merge backend specific data from an object file to the output
4161f7cc78ecSespie    object file when linking.  */
4162d2201f2fSdrahn static bfd_boolean
m32r_elf_merge_private_bfd_data(ibfd,obfd)4163f7cc78ecSespie m32r_elf_merge_private_bfd_data (ibfd, obfd)
4164f7cc78ecSespie      bfd *ibfd;
4165f7cc78ecSespie      bfd *obfd;
4166f7cc78ecSespie {
4167f7cc78ecSespie   flagword out_flags;
4168f7cc78ecSespie   flagword in_flags;
4169f7cc78ecSespie 
4170f7cc78ecSespie   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4171f7cc78ecSespie       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4172d2201f2fSdrahn     return TRUE;
4173f7cc78ecSespie 
4174f7cc78ecSespie   in_flags  = elf_elfheader (ibfd)->e_flags;
4175f7cc78ecSespie   out_flags = elf_elfheader (obfd)->e_flags;
4176f7cc78ecSespie 
4177f7cc78ecSespie   if (! elf_flags_init (obfd))
4178f7cc78ecSespie     {
4179f7cc78ecSespie       /* If the input is the default architecture then do not
4180f7cc78ecSespie 	 bother setting the flags for the output architecture,
4181f7cc78ecSespie 	 instead allow future merges to do this.  If no future
4182f7cc78ecSespie 	 merges ever set these flags then they will retain their
4183f7cc78ecSespie 	 unitialised values, which surprise surprise, correspond
4184f7cc78ecSespie 	 to the default values.  */
4185f7cc78ecSespie       if (bfd_get_arch_info (ibfd)->the_default)
4186d2201f2fSdrahn 	return TRUE;
4187f7cc78ecSespie 
4188d2201f2fSdrahn       elf_flags_init (obfd) = TRUE;
4189f7cc78ecSespie       elf_elfheader (obfd)->e_flags = in_flags;
4190f7cc78ecSespie 
4191f7cc78ecSespie       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4192f7cc78ecSespie 	  && bfd_get_arch_info (obfd)->the_default)
4193f7cc78ecSespie 	{
4194f7cc78ecSespie 	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
4195f7cc78ecSespie 	}
4196f7cc78ecSespie 
4197d2201f2fSdrahn       return TRUE;
4198f7cc78ecSespie     }
4199f7cc78ecSespie 
4200f7cc78ecSespie   /* Check flag compatibility.  */
4201f7cc78ecSespie   if (in_flags == out_flags)
4202d2201f2fSdrahn     return TRUE;
4203f7cc78ecSespie 
4204f7cc78ecSespie   if ((in_flags & EF_M32R_ARCH) != (out_flags & EF_M32R_ARCH))
4205f7cc78ecSespie     {
4206*cf2f2c56Smiod       if (   ((in_flags  & EF_M32R_ARCH) != E_M32R_ARCH)
4207*cf2f2c56Smiod           || ((out_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4208*cf2f2c56Smiod           || ((in_flags  & EF_M32R_ARCH) == E_M32R2_ARCH))
4209f7cc78ecSespie 	{
4210d2201f2fSdrahn 	  (*_bfd_error_handler)
4211d2201f2fSdrahn 	    (_("%s: Instruction set mismatch with previous modules"),
4212d2201f2fSdrahn 	     bfd_archive_filename (ibfd));
4213f7cc78ecSespie 
4214f7cc78ecSespie 	  bfd_set_error (bfd_error_bad_value);
4215d2201f2fSdrahn 	  return FALSE;
4216f7cc78ecSespie 	}
4217f7cc78ecSespie     }
4218f7cc78ecSespie 
4219d2201f2fSdrahn   return TRUE;
4220f7cc78ecSespie }
4221f7cc78ecSespie 
4222f7cc78ecSespie /* Display the flags field */
4223d2201f2fSdrahn static bfd_boolean
m32r_elf_print_private_bfd_data(abfd,ptr)4224f7cc78ecSespie m32r_elf_print_private_bfd_data (abfd, ptr)
4225f7cc78ecSespie      bfd *abfd;
4226f7cc78ecSespie      PTR ptr;
4227f7cc78ecSespie {
4228f7cc78ecSespie   FILE * file = (FILE *) ptr;
4229f7cc78ecSespie 
4230f7cc78ecSespie   BFD_ASSERT (abfd != NULL && ptr != NULL)
4231f7cc78ecSespie 
4232f7cc78ecSespie   _bfd_elf_print_private_bfd_data (abfd, ptr);
4233f7cc78ecSespie 
4234f7cc78ecSespie   fprintf (file, _("private flags = %lx"), elf_elfheader (abfd)->e_flags);
4235f7cc78ecSespie 
4236f7cc78ecSespie   switch (elf_elfheader (abfd)->e_flags & EF_M32R_ARCH)
4237f7cc78ecSespie     {
4238f7cc78ecSespie     default:
4239f7cc78ecSespie     case E_M32R_ARCH:  fprintf (file, _(": m32r instructions"));  break;
4240f7cc78ecSespie     case E_M32RX_ARCH: fprintf (file, _(": m32rx instructions")); break;
4241*cf2f2c56Smiod     case E_M32R2_ARCH: fprintf (file, _(": m32r2 instructions")); break;
4242f7cc78ecSespie     }
4243f7cc78ecSespie 
4244f7cc78ecSespie   fputc ('\n', file);
4245f7cc78ecSespie 
4246d2201f2fSdrahn   return TRUE;
4247f7cc78ecSespie }
4248f7cc78ecSespie 
4249f7cc78ecSespie asection *
m32r_elf_gc_mark_hook(sec,info,rel,h,sym)4250d2201f2fSdrahn m32r_elf_gc_mark_hook (sec, info, rel, h, sym)
4251d2201f2fSdrahn      asection *sec;
4252f7cc78ecSespie      struct bfd_link_info *info ATTRIBUTE_UNUSED;
4253f7cc78ecSespie      Elf_Internal_Rela *rel;
4254f7cc78ecSespie      struct elf_link_hash_entry *h;
4255f7cc78ecSespie      Elf_Internal_Sym *sym;
4256f7cc78ecSespie {
4257f7cc78ecSespie   if (h != NULL)
4258f7cc78ecSespie     {
4259f7cc78ecSespie       switch (ELF32_R_TYPE (rel->r_info))
4260f7cc78ecSespie       {
4261f7cc78ecSespie       case R_M32R_GNU_VTINHERIT:
4262f7cc78ecSespie       case R_M32R_GNU_VTENTRY:
4263*cf2f2c56Smiod       case R_M32R_RELA_GNU_VTINHERIT:
4264*cf2f2c56Smiod       case R_M32R_RELA_GNU_VTENTRY:
4265f7cc78ecSespie         break;
4266f7cc78ecSespie 
4267f7cc78ecSespie       default:
4268f7cc78ecSespie         switch (h->root.type)
4269f7cc78ecSespie           {
4270f7cc78ecSespie           case bfd_link_hash_defined:
4271f7cc78ecSespie           case bfd_link_hash_defweak:
4272f7cc78ecSespie             return h->root.u.def.section;
4273f7cc78ecSespie 
4274f7cc78ecSespie           case bfd_link_hash_common:
4275f7cc78ecSespie             return h->root.u.c.p->section;
4276f7cc78ecSespie 
4277f7cc78ecSespie 	  default:
4278f7cc78ecSespie 	    break;
4279f7cc78ecSespie           }
4280f7cc78ecSespie        }
4281f7cc78ecSespie      }
4282f7cc78ecSespie    else
4283d2201f2fSdrahn      return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
4284d2201f2fSdrahn 
4285f7cc78ecSespie   return NULL;
4286f7cc78ecSespie }
4287f7cc78ecSespie 
4288d2201f2fSdrahn static bfd_boolean
m32r_elf_gc_sweep_hook(abfd,info,sec,relocs)4289f7cc78ecSespie m32r_elf_gc_sweep_hook (abfd, info, sec, relocs)
4290f7cc78ecSespie      bfd *abfd ATTRIBUTE_UNUSED;
4291f7cc78ecSespie      struct bfd_link_info *info ATTRIBUTE_UNUSED;
4292f7cc78ecSespie      asection *sec ATTRIBUTE_UNUSED;
4293f7cc78ecSespie      const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
4294f7cc78ecSespie {
4295*cf2f2c56Smiod   /* Update the got entry reference counts for the section being removed.  */
4296*cf2f2c56Smiod   Elf_Internal_Shdr *symtab_hdr;
4297*cf2f2c56Smiod   struct elf_link_hash_entry **sym_hashes;
4298*cf2f2c56Smiod   bfd_signed_vma *local_got_refcounts;
4299*cf2f2c56Smiod   const Elf_Internal_Rela *rel, *relend;
4300*cf2f2c56Smiod   unsigned long r_symndx;
4301*cf2f2c56Smiod   struct elf_link_hash_entry *h;
4302*cf2f2c56Smiod 
4303*cf2f2c56Smiod   elf_section_data (sec)->local_dynrel = NULL;
4304*cf2f2c56Smiod 
4305*cf2f2c56Smiod   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4306*cf2f2c56Smiod   sym_hashes = elf_sym_hashes (abfd);
4307*cf2f2c56Smiod   local_got_refcounts = elf_local_got_refcounts (abfd);
4308*cf2f2c56Smiod 
4309*cf2f2c56Smiod   relend = relocs + sec->reloc_count;
4310*cf2f2c56Smiod   for (rel = relocs; rel < relend; rel++)
4311*cf2f2c56Smiod     switch (ELF32_R_TYPE (rel->r_info))
4312*cf2f2c56Smiod       {
4313*cf2f2c56Smiod       case R_M32R_GOT16_HI_ULO:
4314*cf2f2c56Smiod       case R_M32R_GOT16_HI_SLO:
4315*cf2f2c56Smiod       case R_M32R_GOT16_LO:
4316*cf2f2c56Smiod       case R_M32R_GOT24:
4317*cf2f2c56Smiod       case R_M32R_GOTPC_HI_ULO:
4318*cf2f2c56Smiod       case R_M32R_GOTPC_HI_SLO:
4319*cf2f2c56Smiod       case R_M32R_GOTPC_LO:
4320*cf2f2c56Smiod       case R_M32R_GOTPC24:
4321*cf2f2c56Smiod 	r_symndx = ELF32_R_SYM (rel->r_info);
4322*cf2f2c56Smiod 	if (r_symndx >= symtab_hdr->sh_info)
4323*cf2f2c56Smiod 	  {
4324*cf2f2c56Smiod 	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4325*cf2f2c56Smiod 	    if (h->got.refcount > 0)
4326*cf2f2c56Smiod 	      h->got.refcount--;
4327*cf2f2c56Smiod 	  }
4328*cf2f2c56Smiod 	else
4329*cf2f2c56Smiod 	  {
4330*cf2f2c56Smiod 	    if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
4331*cf2f2c56Smiod 	      local_got_refcounts[r_symndx]--;
4332*cf2f2c56Smiod 	  }
4333*cf2f2c56Smiod         break;
4334*cf2f2c56Smiod 
4335*cf2f2c56Smiod       case R_M32R_16_RELA:
4336*cf2f2c56Smiod       case R_M32R_24_RELA:
4337*cf2f2c56Smiod       case R_M32R_32_RELA:
4338*cf2f2c56Smiod       case R_M32R_HI16_ULO_RELA:
4339*cf2f2c56Smiod       case R_M32R_HI16_SLO_RELA:
4340*cf2f2c56Smiod       case R_M32R_LO16_RELA:
4341*cf2f2c56Smiod       case R_M32R_SDA16_RELA:
4342*cf2f2c56Smiod       case R_M32R_18_PCREL_RELA:
4343*cf2f2c56Smiod       case R_M32R_26_PCREL_RELA:
4344*cf2f2c56Smiod         r_symndx = ELF32_R_SYM (rel->r_info);
4345*cf2f2c56Smiod         if (r_symndx >= symtab_hdr->sh_info)
4346*cf2f2c56Smiod           {
4347*cf2f2c56Smiod             struct elf_m32r_link_hash_entry *eh;
4348*cf2f2c56Smiod             struct elf_m32r_dyn_relocs **pp;
4349*cf2f2c56Smiod             struct elf_m32r_dyn_relocs *p;
4350*cf2f2c56Smiod 
4351*cf2f2c56Smiod             h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4352*cf2f2c56Smiod 
4353*cf2f2c56Smiod             if (!info->shared && h->plt.refcount > 0)
4354*cf2f2c56Smiod               h->plt.refcount -= 1;
4355*cf2f2c56Smiod 
4356*cf2f2c56Smiod             eh = (struct elf_m32r_link_hash_entry *) h;
4357*cf2f2c56Smiod 
4358*cf2f2c56Smiod             for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
4359*cf2f2c56Smiod               if (p->sec == sec)
4360*cf2f2c56Smiod                 {
4361*cf2f2c56Smiod                   if (ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
4362*cf2f2c56Smiod                       || ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA)
4363*cf2f2c56Smiod                     p->pc_count -= 1;
4364*cf2f2c56Smiod                   p->count -= 1;
4365*cf2f2c56Smiod                   if (p->count == 0)
4366*cf2f2c56Smiod                     *pp = p->next;
4367*cf2f2c56Smiod                   break;
4368*cf2f2c56Smiod                 }
4369*cf2f2c56Smiod           }
4370*cf2f2c56Smiod         break;
4371*cf2f2c56Smiod 
4372*cf2f2c56Smiod       case R_M32R_26_PLTREL:
4373*cf2f2c56Smiod 	r_symndx = ELF32_R_SYM (rel->r_info);
4374*cf2f2c56Smiod 	if (r_symndx >= symtab_hdr->sh_info)
4375*cf2f2c56Smiod 	  {
4376*cf2f2c56Smiod 	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4377*cf2f2c56Smiod 	    if (h->plt.refcount > 0)
4378*cf2f2c56Smiod 	      h->plt.refcount--;
4379*cf2f2c56Smiod 	  }
4380*cf2f2c56Smiod 	break;
4381*cf2f2c56Smiod 
4382*cf2f2c56Smiod       default:
4383*cf2f2c56Smiod 	break;
4384*cf2f2c56Smiod       }
4385*cf2f2c56Smiod 
4386d2201f2fSdrahn   return TRUE;
4387f7cc78ecSespie }
4388f7cc78ecSespie 
4389f7cc78ecSespie /* Look through the relocs for a section during the first phase.
4390f7cc78ecSespie    Since we don't do .gots or .plts, we just need to consider the
4391f7cc78ecSespie    virtual table relocs for gc.  */
4392f7cc78ecSespie 
4393d2201f2fSdrahn static bfd_boolean
m32r_elf_check_relocs(abfd,info,sec,relocs)4394f7cc78ecSespie m32r_elf_check_relocs (abfd, info, sec, relocs)
4395f7cc78ecSespie      bfd *abfd;
4396f7cc78ecSespie      struct bfd_link_info *info;
4397f7cc78ecSespie      asection *sec;
4398f7cc78ecSespie      const Elf_Internal_Rela *relocs;
4399f7cc78ecSespie {
4400f7cc78ecSespie   Elf_Internal_Shdr *symtab_hdr;
4401f7cc78ecSespie   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
4402f7cc78ecSespie   const Elf_Internal_Rela *rel;
4403f7cc78ecSespie   const Elf_Internal_Rela *rel_end;
4404*cf2f2c56Smiod   struct elf_m32r_link_hash_table *htab;
4405*cf2f2c56Smiod   bfd *dynobj;
4406*cf2f2c56Smiod   bfd_vma *local_got_offsets;
4407*cf2f2c56Smiod   asection *sgot, *srelgot, *sreloc;
4408f7cc78ecSespie 
4409*cf2f2c56Smiod   if (info->relocatable)
4410d2201f2fSdrahn     return TRUE;
4411f7cc78ecSespie 
4412*cf2f2c56Smiod   sgot = srelgot = sreloc = NULL;
4413*cf2f2c56Smiod 
4414f7cc78ecSespie   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4415f7cc78ecSespie   sym_hashes = elf_sym_hashes (abfd);
4416f7cc78ecSespie   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
4417f7cc78ecSespie   if (!elf_bad_symtab (abfd))
4418f7cc78ecSespie     sym_hashes_end -= symtab_hdr->sh_info;
4419f7cc78ecSespie 
4420*cf2f2c56Smiod   htab = m32r_elf_hash_table (info);
4421*cf2f2c56Smiod   dynobj = htab->root.dynobj;
4422*cf2f2c56Smiod   local_got_offsets = elf_local_got_offsets (abfd);
4423*cf2f2c56Smiod 
4424f7cc78ecSespie   rel_end = relocs + sec->reloc_count;
4425f7cc78ecSespie   for (rel = relocs; rel < rel_end; rel++)
4426f7cc78ecSespie     {
4427*cf2f2c56Smiod       int r_type;
4428f7cc78ecSespie       struct elf_link_hash_entry *h;
4429f7cc78ecSespie       unsigned long r_symndx;
4430f7cc78ecSespie 
4431f7cc78ecSespie       r_symndx = ELF32_R_SYM (rel->r_info);
4432*cf2f2c56Smiod       r_type = ELF32_R_TYPE (rel->r_info);
4433f7cc78ecSespie       if (r_symndx < symtab_hdr->sh_info)
4434f7cc78ecSespie         h = NULL;
4435f7cc78ecSespie       else
4436f7cc78ecSespie         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4437f7cc78ecSespie 
4438*cf2f2c56Smiod       /* Some relocs require a global offset table.  */
4439*cf2f2c56Smiod       if (htab->sgot == NULL)
4440f7cc78ecSespie         {
4441*cf2f2c56Smiod           switch (r_type)
4442*cf2f2c56Smiod             {
4443*cf2f2c56Smiod             case R_M32R_GOT16_HI_ULO:
4444*cf2f2c56Smiod             case R_M32R_GOT16_HI_SLO:
4445*cf2f2c56Smiod             case R_M32R_GOT16_LO:
4446*cf2f2c56Smiod             case R_M32R_GOTPC24:
4447*cf2f2c56Smiod             case R_M32R_GOTPC_HI_ULO:
4448*cf2f2c56Smiod             case R_M32R_GOTPC_HI_SLO:
4449*cf2f2c56Smiod             case R_M32R_GOTPC_LO:
4450*cf2f2c56Smiod             case R_M32R_GOT24:
4451*cf2f2c56Smiod               if (dynobj == NULL)
4452*cf2f2c56Smiod                 htab->root.dynobj = dynobj = abfd;
4453*cf2f2c56Smiod               if (! create_got_section (dynobj, info))
4454*cf2f2c56Smiod                 return FALSE;
4455*cf2f2c56Smiod               break;
4456*cf2f2c56Smiod 
4457*cf2f2c56Smiod             default:
4458*cf2f2c56Smiod               break;
4459*cf2f2c56Smiod           }
4460*cf2f2c56Smiod         }
4461*cf2f2c56Smiod 
4462*cf2f2c56Smiod       switch (r_type)
4463*cf2f2c56Smiod         {
4464*cf2f2c56Smiod 	case R_M32R_GOT16_HI_ULO:
4465*cf2f2c56Smiod 	case R_M32R_GOT16_HI_SLO:
4466*cf2f2c56Smiod 	case R_M32R_GOT16_LO:
4467*cf2f2c56Smiod         case R_M32R_GOT24:
4468*cf2f2c56Smiod 
4469*cf2f2c56Smiod           if (h != NULL)
4470*cf2f2c56Smiod             h->got.refcount += 1;
4471*cf2f2c56Smiod           else
4472*cf2f2c56Smiod             {
4473*cf2f2c56Smiod               bfd_signed_vma *local_got_refcounts;
4474*cf2f2c56Smiod 
4475*cf2f2c56Smiod               /* This is a global offset table entry for a local
4476*cf2f2c56Smiod                  symbol.  */
4477*cf2f2c56Smiod               local_got_refcounts = elf_local_got_refcounts (abfd);
4478*cf2f2c56Smiod               if (local_got_refcounts == NULL)
4479*cf2f2c56Smiod                 {
4480*cf2f2c56Smiod                   bfd_size_type size;
4481*cf2f2c56Smiod 
4482*cf2f2c56Smiod                   size = symtab_hdr->sh_info;
4483*cf2f2c56Smiod                   size *= sizeof (bfd_signed_vma);
4484*cf2f2c56Smiod                   local_got_refcounts = ((bfd_signed_vma *)
4485*cf2f2c56Smiod                                          bfd_zalloc (abfd, size));
4486*cf2f2c56Smiod                   if (local_got_refcounts == NULL)
4487*cf2f2c56Smiod                     return FALSE;
4488*cf2f2c56Smiod                   elf_local_got_refcounts (abfd) = local_got_refcounts;
4489*cf2f2c56Smiod                 }
4490*cf2f2c56Smiod               local_got_refcounts[r_symndx] += 1;
4491*cf2f2c56Smiod             }
4492*cf2f2c56Smiod           break;
4493*cf2f2c56Smiod 
4494*cf2f2c56Smiod         case R_M32R_26_PLTREL:
4495*cf2f2c56Smiod           /* This symbol requires a procedure linkage table entry.  We
4496*cf2f2c56Smiod              actually build the entry in adjust_dynamic_symbol,
4497*cf2f2c56Smiod              because this might be a case of linking PIC code without
4498*cf2f2c56Smiod              linking in any dynamic objects, in which case we don't
4499*cf2f2c56Smiod              need to generate a procedure linkage table after all.  */
4500*cf2f2c56Smiod 
4501*cf2f2c56Smiod 	  /* If this is a local symbol, we resolve it directly without
4502*cf2f2c56Smiod 	     creating a procedure linkage table entry.  */
4503*cf2f2c56Smiod           if (h == NULL)
4504*cf2f2c56Smiod             continue;
4505*cf2f2c56Smiod 
4506*cf2f2c56Smiod           if (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)
4507*cf2f2c56Smiod             break;
4508*cf2f2c56Smiod 
4509*cf2f2c56Smiod           h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
4510*cf2f2c56Smiod 	  h->plt.refcount += 1;
4511*cf2f2c56Smiod           break;
4512*cf2f2c56Smiod 
4513*cf2f2c56Smiod         case R_M32R_16_RELA:
4514*cf2f2c56Smiod         case R_M32R_24_RELA:
4515*cf2f2c56Smiod         case R_M32R_32_RELA:
4516*cf2f2c56Smiod         case R_M32R_HI16_ULO_RELA:
4517*cf2f2c56Smiod         case R_M32R_HI16_SLO_RELA:
4518*cf2f2c56Smiod         case R_M32R_LO16_RELA:
4519*cf2f2c56Smiod         case R_M32R_SDA16_RELA:
4520*cf2f2c56Smiod         case R_M32R_18_PCREL_RELA:
4521*cf2f2c56Smiod         case R_M32R_26_PCREL_RELA:
4522*cf2f2c56Smiod 
4523*cf2f2c56Smiod           if (h != NULL && !info->shared)
4524*cf2f2c56Smiod             {
4525*cf2f2c56Smiod               h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
4526*cf2f2c56Smiod               h->plt.refcount += 1;
4527*cf2f2c56Smiod             }
4528*cf2f2c56Smiod 
4529*cf2f2c56Smiod           /* If we are creating a shared library, and this is a reloc
4530*cf2f2c56Smiod              against a global symbol, or a non PC relative reloc
4531*cf2f2c56Smiod              against a local symbol, then we need to copy the reloc
4532*cf2f2c56Smiod              into the shared library.  However, if we are linking with
4533*cf2f2c56Smiod              -Bsymbolic, we do not need to copy a reloc against a
4534*cf2f2c56Smiod              global symbol which is defined in an object we are
4535*cf2f2c56Smiod              including in the link (i.e., DEF_REGULAR is set).  At
4536*cf2f2c56Smiod              this point we have not seen all the input files, so it is
4537*cf2f2c56Smiod              possible that DEF_REGULAR is not set now but will be set
4538*cf2f2c56Smiod              later (it is never cleared).  We account for that
4539*cf2f2c56Smiod              possibility below by storing information in the
4540*cf2f2c56Smiod              dyn_relocs field of the hash table entry. A similar
4541*cf2f2c56Smiod              situation occurs when creating shared libraries and symbol
4542*cf2f2c56Smiod              visibility changes render the symbol local.
4543*cf2f2c56Smiod 
4544*cf2f2c56Smiod              If on the other hand, we are creating an executable, we
4545*cf2f2c56Smiod              may need to keep relocations for symbols satisfied by a
4546*cf2f2c56Smiod              dynamic library if we manage to avoid copy relocs for the
4547*cf2f2c56Smiod              symbol.  */
4548*cf2f2c56Smiod           if ((info->shared
4549*cf2f2c56Smiod                && (sec->flags & SEC_ALLOC) != 0
4550*cf2f2c56Smiod 	       && ((r_type != R_M32R_26_PCREL_RELA
4551*cf2f2c56Smiod                     && r_type != R_M32R_18_PCREL_RELA)
4552*cf2f2c56Smiod 	           || (h != NULL
4553*cf2f2c56Smiod 		       && (! info->symbolic
4554*cf2f2c56Smiod 		           || h->root.type == bfd_link_hash_defweak
4555*cf2f2c56Smiod 		           || (h->elf_link_hash_flags
4556*cf2f2c56Smiod 		               & ELF_LINK_HASH_DEF_REGULAR) == 0))))
4557*cf2f2c56Smiod               || (!info->shared
4558*cf2f2c56Smiod                   && (sec->flags & SEC_ALLOC) != 0
4559*cf2f2c56Smiod                   && h != NULL
4560*cf2f2c56Smiod                   && (h->root.type == bfd_link_hash_defweak
4561*cf2f2c56Smiod                       || (h->elf_link_hash_flags
4562*cf2f2c56Smiod                           & ELF_LINK_HASH_DEF_REGULAR) == 0)))
4563*cf2f2c56Smiod             {
4564*cf2f2c56Smiod               struct elf_m32r_dyn_relocs *p;
4565*cf2f2c56Smiod               struct elf_m32r_dyn_relocs **head;
4566*cf2f2c56Smiod 
4567*cf2f2c56Smiod               if (dynobj == NULL)
4568*cf2f2c56Smiod                 htab->root.dynobj = dynobj = abfd;
4569*cf2f2c56Smiod 
4570*cf2f2c56Smiod               /* When creating a shared object, we must copy these
4571*cf2f2c56Smiod                  relocs into the output file.  We create a reloc
4572*cf2f2c56Smiod                  section in dynobj and make room for the reloc.  */
4573*cf2f2c56Smiod               if (sreloc == NULL)
4574*cf2f2c56Smiod                 {
4575*cf2f2c56Smiod                   const char *name;
4576*cf2f2c56Smiod 
4577*cf2f2c56Smiod                   name = (bfd_elf_string_from_elf_section
4578*cf2f2c56Smiod                           (abfd,
4579*cf2f2c56Smiod                            elf_elfheader (abfd)->e_shstrndx,
4580*cf2f2c56Smiod                            elf_section_data (sec)->rel_hdr.sh_name));
4581*cf2f2c56Smiod                   if (name == NULL)
4582*cf2f2c56Smiod                     return FALSE;
4583*cf2f2c56Smiod 
4584*cf2f2c56Smiod                   BFD_ASSERT (strncmp (name, ".rela", 5) == 0
4585*cf2f2c56Smiod                               && strcmp (bfd_get_section_name (abfd, sec),
4586*cf2f2c56Smiod                                          name + 5) == 0);
4587*cf2f2c56Smiod 
4588*cf2f2c56Smiod                   sreloc = bfd_get_section_by_name (dynobj, name);
4589*cf2f2c56Smiod                   if (sreloc == NULL)
4590*cf2f2c56Smiod                     {
4591*cf2f2c56Smiod                       flagword flags;
4592*cf2f2c56Smiod 
4593*cf2f2c56Smiod                       sreloc = bfd_make_section (dynobj, name);
4594*cf2f2c56Smiod                       flags = (SEC_HAS_CONTENTS | SEC_READONLY
4595*cf2f2c56Smiod                                | SEC_IN_MEMORY | SEC_LINKER_CREATED);
4596*cf2f2c56Smiod                       if ((sec->flags & SEC_ALLOC) != 0)
4597*cf2f2c56Smiod                         flags |= SEC_ALLOC | SEC_LOAD;
4598*cf2f2c56Smiod                       if (sreloc == NULL
4599*cf2f2c56Smiod                           || ! bfd_set_section_flags (dynobj, sreloc, flags)
4600*cf2f2c56Smiod                           || ! bfd_set_section_alignment (dynobj, sreloc, 2))
4601*cf2f2c56Smiod                         return FALSE;
4602*cf2f2c56Smiod                     }
4603*cf2f2c56Smiod                   elf_section_data (sec)->sreloc = sreloc;
4604*cf2f2c56Smiod                 }
4605*cf2f2c56Smiod 
4606*cf2f2c56Smiod               /* If this is a global symbol, we count the number of
4607*cf2f2c56Smiod                  relocations we need for this symbol.  */
4608*cf2f2c56Smiod               if (h != NULL)
4609*cf2f2c56Smiod                 head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs;
4610*cf2f2c56Smiod               else
4611*cf2f2c56Smiod                 {
4612*cf2f2c56Smiod                   asection *s;
4613*cf2f2c56Smiod 
4614*cf2f2c56Smiod                   /* Track dynamic relocs needed for local syms too.  */
4615*cf2f2c56Smiod                   s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
4616*cf2f2c56Smiod                                                  sec, r_symndx);
4617*cf2f2c56Smiod                   if (s == NULL)
4618*cf2f2c56Smiod                     return FALSE;
4619*cf2f2c56Smiod 
4620*cf2f2c56Smiod                   head = ((struct elf_m32r_dyn_relocs **)
4621*cf2f2c56Smiod                           &elf_section_data (s)->local_dynrel);
4622*cf2f2c56Smiod                 }
4623*cf2f2c56Smiod 
4624*cf2f2c56Smiod               p = *head;
4625*cf2f2c56Smiod               if (p == NULL || p->sec != sec)
4626*cf2f2c56Smiod                 {
4627*cf2f2c56Smiod                   bfd_size_type amt = sizeof (*p);
4628*cf2f2c56Smiod                   p = ((struct elf_m32r_dyn_relocs *) bfd_alloc (dynobj, amt));
4629*cf2f2c56Smiod                   if (p == NULL)
4630*cf2f2c56Smiod                     return FALSE;
4631*cf2f2c56Smiod                   p->next = *head;
4632*cf2f2c56Smiod                   *head = p;
4633*cf2f2c56Smiod                   p->sec = sec;
4634*cf2f2c56Smiod                   p->count = 0;
4635*cf2f2c56Smiod                   p->pc_count = 0;
4636*cf2f2c56Smiod                 }
4637*cf2f2c56Smiod 
4638*cf2f2c56Smiod               p->count += 1;
4639*cf2f2c56Smiod               if (ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
4640*cf2f2c56Smiod                   || ELF32_R_TYPE (rel->r_info) == R_M32R_18_PCREL_RELA)
4641*cf2f2c56Smiod                 p->pc_count += 1;
4642*cf2f2c56Smiod             }
4643*cf2f2c56Smiod           break;
4644*cf2f2c56Smiod 
4645f7cc78ecSespie         /* This relocation describes the C++ object vtable hierarchy.
4646f7cc78ecSespie            Reconstruct it for later use during GC.  */
4647*cf2f2c56Smiod         case R_M32R_RELA_GNU_VTINHERIT:
4648f7cc78ecSespie         case R_M32R_GNU_VTINHERIT:
4649*cf2f2c56Smiod           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
4650d2201f2fSdrahn             return FALSE;
4651f7cc78ecSespie           break;
4652f7cc78ecSespie 
4653f7cc78ecSespie         /* This relocation describes which C++ vtable entries are actually
4654f7cc78ecSespie            used.  Record for later use during GC.  */
4655f7cc78ecSespie         case R_M32R_GNU_VTENTRY:
4656*cf2f2c56Smiod           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
4657*cf2f2c56Smiod             return FALSE;
4658*cf2f2c56Smiod           break;
4659*cf2f2c56Smiod         case R_M32R_RELA_GNU_VTENTRY:
4660*cf2f2c56Smiod           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
4661d2201f2fSdrahn             return FALSE;
4662f7cc78ecSespie           break;
4663f7cc78ecSespie         }
4664f7cc78ecSespie     }
4665f7cc78ecSespie 
4666d2201f2fSdrahn   return TRUE;
4667f7cc78ecSespie }
4668*cf2f2c56Smiod 
4669*cf2f2c56Smiod static struct bfd_elf_special_section const m32r_elf_special_sections[]=
4670*cf2f2c56Smiod {
4671*cf2f2c56Smiod   { ".sdata",   6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
4672*cf2f2c56Smiod   { ".sbss",    5, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
4673*cf2f2c56Smiod   { NULL,       0,  0, 0,            0 }
4674*cf2f2c56Smiod };
4675*cf2f2c56Smiod 
4676*cf2f2c56Smiod static bfd_boolean
m32r_elf_fake_sections(abfd,hdr,sec)4677*cf2f2c56Smiod m32r_elf_fake_sections (abfd, hdr, sec)
4678*cf2f2c56Smiod      bfd *abfd;
4679*cf2f2c56Smiod      Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED;
4680*cf2f2c56Smiod      asection *sec;
4681*cf2f2c56Smiod {
4682*cf2f2c56Smiod   register const char *name;
4683*cf2f2c56Smiod 
4684*cf2f2c56Smiod   name = bfd_get_section_name (abfd, sec);
4685*cf2f2c56Smiod 
4686*cf2f2c56Smiod   /* The generic elf_fake_sections will set up REL_HDR using the
4687*cf2f2c56Smiod      default kind of relocations.  But, we may actually need both
4688*cf2f2c56Smiod      kinds of relocations, so we set up the second header here.
4689*cf2f2c56Smiod 
4690*cf2f2c56Smiod      This is not necessary for the O32 ABI since that only uses Elf32_Rel
4691*cf2f2c56Smiod      relocations (cf. System V ABI, MIPS RISC Processor Supplement,
4692*cf2f2c56Smiod      3rd Edition, p. 4-17).  It breaks the IRIX 5/6 32-bit ld, since one
4693*cf2f2c56Smiod      of the resulting empty .rela.<section> sections starts with
4694*cf2f2c56Smiod      sh_offset == object size, and ld doesn't allow that.  While the check
4695*cf2f2c56Smiod      is arguably bogus for empty or SHT_NOBITS sections, it can easily be
4696*cf2f2c56Smiod      avoided by not emitting those useless sections in the first place.  */
4697*cf2f2c56Smiod   if ((sec->flags & SEC_RELOC) != 0)
4698*cf2f2c56Smiod     {
4699*cf2f2c56Smiod       struct bfd_elf_section_data *esd;
4700*cf2f2c56Smiod       bfd_size_type amt = sizeof (Elf_Internal_Shdr);
4701*cf2f2c56Smiod 
4702*cf2f2c56Smiod       esd = elf_section_data (sec);
4703*cf2f2c56Smiod       BFD_ASSERT (esd->rel_hdr2 == NULL);
4704*cf2f2c56Smiod       esd->rel_hdr2 = (Elf_Internal_Shdr *) bfd_zalloc (abfd, amt);
4705*cf2f2c56Smiod       if (!esd->rel_hdr2)
4706*cf2f2c56Smiod         return FALSE;
4707*cf2f2c56Smiod       _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
4708*cf2f2c56Smiod                                 !sec->use_rela_p);
4709*cf2f2c56Smiod     }
4710*cf2f2c56Smiod 
4711*cf2f2c56Smiod   return TRUE;
4712*cf2f2c56Smiod }
4713*cf2f2c56Smiod 
4714*cf2f2c56Smiod static enum elf_reloc_type_class
m32r_elf_reloc_type_class(rela)4715*cf2f2c56Smiod m32r_elf_reloc_type_class (rela)
4716*cf2f2c56Smiod      const Elf_Internal_Rela *rela;
4717*cf2f2c56Smiod {
4718*cf2f2c56Smiod   switch ((int) ELF32_R_TYPE (rela->r_info))
4719*cf2f2c56Smiod     {
4720*cf2f2c56Smiod     case R_M32R_RELATIVE:
4721*cf2f2c56Smiod       return reloc_class_relative;
4722*cf2f2c56Smiod     case R_M32R_JMP_SLOT:
4723*cf2f2c56Smiod       return reloc_class_plt;
4724*cf2f2c56Smiod     case R_M32R_COPY:
4725*cf2f2c56Smiod       return reloc_class_copy;
4726*cf2f2c56Smiod     default:
4727*cf2f2c56Smiod       return reloc_class_normal;
4728*cf2f2c56Smiod     }
4729*cf2f2c56Smiod }
4730f7cc78ecSespie 
4731fddef416Sniklas #define ELF_ARCH		bfd_arch_m32r
4732d2201f2fSdrahn #define ELF_MACHINE_CODE	EM_M32R
4733d2201f2fSdrahn #define ELF_MACHINE_ALT1	EM_CYGNUS_M32R
4734f7cc78ecSespie #define ELF_MAXPAGESIZE		0x1 /* Explicitly requested by Mitsubishi.  */
4735fddef416Sniklas 
4736fddef416Sniklas #define TARGET_BIG_SYM          bfd_elf32_m32r_vec
4737fddef416Sniklas #define TARGET_BIG_NAME		"elf32-m32r"
4738*cf2f2c56Smiod #define TARGET_LITTLE_SYM       bfd_elf32_m32rle_vec
4739*cf2f2c56Smiod #define TARGET_LITTLE_NAME      "elf32-m32rle"
4740fddef416Sniklas 
4741*cf2f2c56Smiod #define elf_info_to_howto			m32r_info_to_howto
4742fddef416Sniklas #define elf_info_to_howto_rel			m32r_info_to_howto_rel
4743fddef416Sniklas #define elf_backend_section_from_bfd_section	_bfd_m32r_elf_section_from_bfd_section
4744fddef416Sniklas #define elf_backend_symbol_processing		_bfd_m32r_elf_symbol_processing
4745fddef416Sniklas #define elf_backend_add_symbol_hook		m32r_elf_add_symbol_hook
4746fddef416Sniklas #define elf_backend_relocate_section		m32r_elf_relocate_section
4747f7cc78ecSespie #define elf_backend_gc_mark_hook                m32r_elf_gc_mark_hook
4748f7cc78ecSespie #define elf_backend_gc_sweep_hook               m32r_elf_gc_sweep_hook
4749f7cc78ecSespie #define elf_backend_check_relocs                m32r_elf_check_relocs
4750fddef416Sniklas 
4751*cf2f2c56Smiod #define elf_backend_create_dynamic_sections     m32r_elf_create_dynamic_sections
4752*cf2f2c56Smiod #define bfd_elf32_bfd_link_hash_table_create    m32r_elf_link_hash_table_create
4753*cf2f2c56Smiod #define elf_backend_size_dynamic_sections       m32r_elf_size_dynamic_sections
4754*cf2f2c56Smiod #define elf_backend_finish_dynamic_sections     m32r_elf_finish_dynamic_sections
4755*cf2f2c56Smiod #define elf_backend_adjust_dynamic_symbol       m32r_elf_adjust_dynamic_symbol
4756*cf2f2c56Smiod #define elf_backend_finish_dynamic_symbol       m32r_elf_finish_dynamic_symbol
4757*cf2f2c56Smiod #define elf_backend_reloc_type_class            m32r_elf_reloc_type_class
4758*cf2f2c56Smiod #define elf_backend_copy_indirect_symbol        m32r_elf_copy_indirect_symbol
4759*cf2f2c56Smiod 
4760f7cc78ecSespie #define elf_backend_can_gc_sections             1
4761*cf2f2c56Smiod /*#if !USE_REL
4762d2201f2fSdrahn #define elf_backend_rela_normal			1
4763*cf2f2c56Smiod #endif*/
4764*cf2f2c56Smiod #define elf_backend_can_refcount 1
4765*cf2f2c56Smiod #define elf_backend_want_got_plt 1
4766*cf2f2c56Smiod #define elf_backend_plt_readonly 1
4767*cf2f2c56Smiod #define elf_backend_want_plt_sym 0
4768*cf2f2c56Smiod #define elf_backend_got_header_size 12
4769*cf2f2c56Smiod 
4770*cf2f2c56Smiod #define elf_backend_may_use_rel_p       1
4771*cf2f2c56Smiod #ifdef USE_M32R_OLD_RELOC
4772*cf2f2c56Smiod #define elf_backend_default_use_rela_p  0
4773*cf2f2c56Smiod #define elf_backend_may_use_rela_p      0
4774*cf2f2c56Smiod #else
4775*cf2f2c56Smiod #define elf_backend_default_use_rela_p  1
4776*cf2f2c56Smiod #define elf_backend_may_use_rela_p      1
4777*cf2f2c56Smiod #define elf_backend_fake_sections       m32r_elf_fake_sections
4778d2201f2fSdrahn #endif
4779*cf2f2c56Smiod 
4780fddef416Sniklas #if 0 /* not yet */
4781fddef416Sniklas /* relax support */
4782fddef416Sniklas #define bfd_elf32_bfd_relax_section		m32r_elf_relax_section
4783fddef416Sniklas #define bfd_elf32_bfd_get_relocated_section_contents \
4784fddef416Sniklas 					m32r_elf_get_relocated_section_contents
4785fddef416Sniklas #endif
4786fddef416Sniklas 
4787f7cc78ecSespie #define elf_backend_object_p			m32r_elf_object_p
4788f7cc78ecSespie #define elf_backend_final_write_processing 	m32r_elf_final_write_processing
4789f7cc78ecSespie #define bfd_elf32_bfd_merge_private_bfd_data 	m32r_elf_merge_private_bfd_data
4790f7cc78ecSespie #define bfd_elf32_bfd_set_private_flags		m32r_elf_set_private_flags
4791f7cc78ecSespie #define bfd_elf32_bfd_print_private_bfd_data	m32r_elf_print_private_bfd_data
4792*cf2f2c56Smiod #define elf_backend_special_sections		m32r_elf_special_sections
4793f7cc78ecSespie 
4794fddef416Sniklas #include "elf32-target.h"
4795*cf2f2c56Smiod 
4796*cf2f2c56Smiod #undef ELF_MAXPAGESIZE
4797*cf2f2c56Smiod #define ELF_MAXPAGESIZE         0x1000
4798*cf2f2c56Smiod 
4799*cf2f2c56Smiod #undef TARGET_BIG_SYM
4800*cf2f2c56Smiod #define TARGET_BIG_SYM          bfd_elf32_m32rlin_vec
4801*cf2f2c56Smiod #undef TARGET_BIG_NAME
4802*cf2f2c56Smiod #define TARGET_BIG_NAME         "elf32-m32r-linux"
4803*cf2f2c56Smiod #undef TARGET_LITTLE_SYM
4804*cf2f2c56Smiod #define TARGET_LITTLE_SYM       bfd_elf32_m32rlelin_vec
4805*cf2f2c56Smiod #undef TARGET_LITTLE_NAME
4806*cf2f2c56Smiod #define TARGET_LITTLE_NAME      "elf32-m32rle-linux"
4807*cf2f2c56Smiod #undef elf32_bed
4808*cf2f2c56Smiod #define elf32_bed               elf32_m32r_lin_bed
4809*cf2f2c56Smiod 
4810*cf2f2c56Smiod #include "elf32-target.h"
4811*cf2f2c56Smiod 
4812