* elf32-mn10300.c (elf_symbol_leading_char): Define.
[deliverable/binutils-gdb.git] / bfd / elf32-mn10300.c
1 /* Matsushita 10300 specific support for 32-bit ELF
2 Copyright (C) 1996 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24
25 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
26 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
27 static void mn10300_info_to_howto
28 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
29 static bfd_reloc_status_type bfd_elf32_mn10300_reloc
30 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
31
32
33 /* We have to use RELA instructions since md_apply_fix3 in the assembler
34 does absolutely nothing. */
35 #define USE_RELA
36
37 enum reloc_type
38 {
39 R_MN10300_NONE = 0,
40 R_MN10300_32,
41 R_MN10300_16,
42 R_MN10300_8,
43 R_MN10300_32B,
44 R_MN10300_16B,
45 R_MN10300_PCREL32_1BYTE,
46 R_MN10300_PCREL16_1BYTE,
47 R_MN10300_PCREL8_1BYTE,
48 R_MN10300_PCREL32_2BYTE,
49 R_MN10300_PCREL16_2BYTE,
50 R_MN10300_MAX
51 };
52
53 static reloc_howto_type elf_mn10300_howto_table[] =
54 {
55 /* Dummy relocation. Does nothing. */
56 HOWTO (R_MN10300_NONE,
57 0,
58 2,
59 16,
60 false,
61 0,
62 complain_overflow_bitfield,
63 bfd_elf_generic_reloc,
64 "R_MN10300_NONE",
65 false,
66 0,
67 0,
68 false),
69 /* Standard 32 bit reloc. */
70 HOWTO (R_MN10300_32,
71 0,
72 2,
73 32,
74 false,
75 0,
76 complain_overflow_bitfield,
77 bfd_elf_generic_reloc,
78 "R_MN10300_32",
79 false,
80 0xffffffff,
81 0xffffffff,
82 false),
83 /* Standard 16 bit reloc. */
84 HOWTO (R_MN10300_16,
85 0,
86 1,
87 16,
88 false,
89 0,
90 complain_overflow_bitfield,
91 bfd_elf_generic_reloc,
92 "R_MN10300_16",
93 false,
94 0xffff,
95 0xffff,
96 false),
97 /* Standard 8 bit reloc. */
98 HOWTO (R_MN10300_8,
99 0,
100 0,
101 8,
102 false,
103 0,
104 complain_overflow_bitfield,
105 bfd_elf_generic_reloc,
106 "R_MN10300_8",
107 false,
108 0xff,
109 0xff,
110 false),
111 /* Standard 32 bit reloc, except it explicitly writes big-endian format. */
112 HOWTO (R_MN10300_32B,
113 0,
114 2,
115 32,
116 false,
117 0,
118 complain_overflow_bitfield,
119 bfd_elf32_mn10300_reloc,
120 "R_MN10300_32B",
121 false,
122 0xffffffff,
123 0xffffffff,
124 false),
125 /* Standard 16 bit reloc, except it explicitly writes big-endian format. */
126 HOWTO (R_MN10300_16B,
127 0,
128 1,
129 16,
130 false,
131 0,
132 complain_overflow_bitfield,
133 bfd_elf32_mn10300_reloc,
134 "R_MN10300_16B",
135 false,
136 0xffff,
137 0xffff,
138 false),
139 /* Simple 32bit pc-relative reloc with a 1 byte adjustment
140 to get the pc-relative offset correct. */
141 HOWTO (R_MN10300_PCREL32_1BYTE,
142 0,
143 2,
144 32,
145 true,
146 0,
147 complain_overflow_bitfield,
148 bfd_elf32_mn10300_reloc,
149 "R_MN10300_PCREL32_1BYTE",
150 true,
151 0xffffffff,
152 0xffffffff,
153 false),
154 /* Simple 16bit pc-relative reloc with a 1 byte adjustment
155 to get the pc-relative offset correct. */
156 HOWTO (R_MN10300_PCREL16_1BYTE,
157 0,
158 1,
159 16,
160 true,
161 0,
162 complain_overflow_bitfield,
163 bfd_elf32_mn10300_reloc,
164 "R_MN10300_PCREL16_1BYTE",
165 true,
166 0xffff,
167 0xffff,
168 false),
169 /* Simple 8 pc-relative reloc with a 1 byte adjustment
170 to get the pc-relative offset correct. */
171 HOWTO (R_MN10300_PCREL8_1BYTE,
172 0,
173 0,
174 8,
175 true,
176 0,
177 complain_overflow_bitfield,
178 bfd_elf32_mn10300_reloc,
179 "R_MN10300_PCREL8_1BYTE",
180 true,
181 0xff,
182 0xff,
183 true),
184 /* Simple 32 pc-relative reloc with a 2 byte adjustment
185 to get the pc-relative offset correct. */
186 HOWTO (R_MN10300_PCREL32_2BYTE,
187 0,
188 2,
189 32,
190 true,
191 0,
192 complain_overflow_bitfield,
193 bfd_elf32_mn10300_reloc,
194 "R_MN10300_PCREL32_2BYTE",
195 true,
196 0xffffffff,
197 0xffffffff,
198 true),
199 /* Simple 16 pc-relative reloc with a 2 byte adjustment
200 to get the pc-relative offset correct. */
201 HOWTO (R_MN10300_PCREL16_2BYTE,
202 0,
203 1,
204 16,
205 true,
206 0,
207 complain_overflow_bitfield,
208 bfd_elf32_mn10300_reloc,
209 "R_MN10300_PCREL16_2BYTE",
210 true,
211 0xffff,
212 0xffff,
213 true),
214 };
215
216 struct mn10300_reloc_map
217 {
218 unsigned char bfd_reloc_val;
219 unsigned char elf_reloc_val;
220 };
221
222 static const struct mn10300_reloc_map mn10300_reloc_map[] =
223 {
224 { BFD_RELOC_NONE, R_MN10300_NONE, },
225 { BFD_RELOC_32, R_MN10300_32, },
226 { BFD_RELOC_16, R_MN10300_16, },
227 { BFD_RELOC_8, R_MN10300_8, },
228 { BFD_RELOC_MN10300_32B, R_MN10300_32B, },
229 { BFD_RELOC_MN10300_16B, R_MN10300_16B, },
230 { BFD_RELOC_32_PCREL, R_MN10300_PCREL32_1BYTE, },
231 { BFD_RELOC_16_PCREL, R_MN10300_PCREL16_1BYTE, },
232 { BFD_RELOC_8_PCREL, R_MN10300_PCREL8_1BYTE, },
233 { BFD_RELOC_MN10300_32_PCREL, R_MN10300_PCREL32_2BYTE, },
234 { BFD_RELOC_MN10300_16_PCREL, R_MN10300_PCREL16_2BYTE, },
235 };
236
237 static reloc_howto_type *
238 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
239 bfd *abfd;
240 bfd_reloc_code_real_type code;
241 {
242 unsigned int i;
243
244 for (i = 0;
245 i < sizeof (mn10300_reloc_map) / sizeof (struct mn10300_reloc_map);
246 i++)
247 {
248 if (mn10300_reloc_map[i].bfd_reloc_val == code)
249 return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val];
250 }
251
252 return NULL;
253 }
254
255 /* Set the howto pointer for an MN10300 ELF reloc. */
256
257 static void
258 mn10300_info_to_howto (abfd, cache_ptr, dst)
259 bfd *abfd;
260 arelent *cache_ptr;
261 Elf32_Internal_Rela *dst;
262 {
263 unsigned int r_type;
264
265 r_type = ELF32_R_TYPE (dst->r_info);
266 BFD_ASSERT (r_type < (unsigned int) R_MN10300_MAX);
267 cache_ptr->howto = &elf_mn10300_howto_table[r_type];
268 }
269
270 static bfd_reloc_status_type
271 bfd_elf32_mn10300_reloc (abfd, reloc, symbol, data, isection, obfd, err)
272 bfd *abfd;
273 arelent *reloc;
274 asymbol *symbol;
275 PTR data;
276 asection *isection;
277 bfd *obfd;
278 char **err;
279 {
280 if (obfd != (bfd *) NULL
281 && (symbol->flags & BSF_SECTION_SYM) == 0
282 && (! reloc->howto->partial_inplace
283 || reloc->addend == 0))
284 {
285 reloc->address += isection->output_offset;
286 return bfd_reloc_ok;
287 }
288 else if (obfd != NULL)
289 {
290 return bfd_reloc_continue;
291 }
292
293 /* Catch relocs involving undefined symbols. */
294 if (bfd_is_und_section (symbol->section)
295 && (symbol->flags & BSF_WEAK) == 0
296 && obfd == NULL)
297 return bfd_reloc_undefined;
298
299 /* We handle final linking of some relocs ourselves. */
300 {
301 long relocation;
302
303 /* Is the address of the relocation really within the section? */
304 if (reloc->address > isection->_cooked_size)
305 return bfd_reloc_outofrange;
306
307 /* Work out which section the relocation is targetted at and the
308 initial relocation command value. */
309
310 /* Get symbol value. (Common symbols are special.) */
311 if (bfd_is_com_section (symbol->section))
312 relocation = 0;
313 else
314 relocation = symbol->value;
315
316 /* Convert input-section-relative symbol value to absolute + addend. */
317 relocation += symbol->section->output_section->vma;
318 relocation += symbol->section->output_offset;
319 relocation += reloc->addend;
320
321 if (reloc->howto->pc_relative == true)
322 {
323 /* Here the variable relocation holds the final address of the
324 symbol we are relocating against, plus any addend. */
325 relocation -= isection->output_section->vma + isection->output_offset;
326
327 /* Deal with pcrel_offset */
328 relocation -= reloc->address;
329
330 if (reloc->howto->type == R_MN10300_PCREL32_1BYTE
331 || reloc->howto->type == R_MN10300_PCREL16_1BYTE
332 || reloc->howto->type == R_MN10300_PCREL8_1BYTE)
333 relocation += 1;
334 else if (reloc->howto->type == R_MN10300_PCREL32_2BYTE
335 || reloc->howto->type == R_MN10300_PCREL16_2BYTE)
336 relocation += 2;
337 }
338
339 /* I've got no clue... */
340 reloc->addend = 0;
341
342 if (reloc->howto->size == 0)
343 {
344 if (relocation > 0x7f || relocation < -0x80)
345 return bfd_reloc_overflow;
346
347 bfd_put_8 (abfd, relocation & 0xff,
348 (bfd_byte *)data + reloc->address);
349 }
350 else if (reloc->howto->size == 1)
351 {
352 if (relocation > 0x7fff || relocation < -0x8000)
353 return bfd_reloc_overflow;
354
355 bfd_putb16 (relocation & 0xffff, (bfd_byte *)data + reloc->address);
356 }
357 else if (reloc->howto->size == 2)
358 bfd_putb32 (relocation, (bfd_byte *)data + reloc->address);
359 return bfd_reloc_ok;
360 }
361
362 return bfd_reloc_continue;
363 }
364
365 #define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec
366 #define TARGET_LITTLE_NAME "elf32-mn10300"
367 #define ELF_ARCH bfd_arch_mn10300
368 #define ELF_MACHINE_CODE EM_CYGNUS_MN10300
369 #define ELF_MAXPAGESIZE 0x1000
370
371 #define elf_info_to_howto mn10300_info_to_howto
372 #define elf_info_to_howto_rel 0
373
374 #define elf_symbol_leading_char '_'
375
376 #include "elf32-target.h"
This page took 0.036187 seconds and 4 git commands to generate.