Tue Mar 18 22:40:09 1997 H.J. Lu <hjl@lucon.org>
[deliverable/binutils-gdb.git] / bfd / elf32-mn10300.c
CommitLineData
ae1b99e4 1/* Matsushita 10300 specific support for 32-bit ELF
8821be29 2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
efc2b064
JL
3
4This file is part of BFD, the Binary File Descriptor library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, 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
25static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
26 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
943686fa
JL
27static void mn10300_info_to_howto
28 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
12fdaaf8
JL
29static bfd_reloc_status_type bfd_elf32_mn10300_reloc
30 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
31
efc2b064 32
943686fa
JL
33/* We have to use RELA instructions since md_apply_fix3 in the assembler
34 does absolutely nothing. */
35#define USE_RELA
efc2b064
JL
36
37enum reloc_type
38{
ae1b99e4 39 R_MN10300_NONE = 0,
c3239e66
JL
40 R_MN10300_32,
41 R_MN10300_16,
42 R_MN10300_8,
77bf22e6
JL
43 R_MN10300_PCREL32,
44 R_MN10300_PCREL16,
45 R_MN10300_PCREL8,
ae1b99e4 46 R_MN10300_MAX
efc2b064
JL
47};
48
ae1b99e4 49static reloc_howto_type elf_mn10300_howto_table[] =
efc2b064 50{
207e944c 51 /* Dummy relocation. Does nothing. */
ae1b99e4 52 HOWTO (R_MN10300_NONE,
efc2b064
JL
53 0,
54 2,
55 16,
56 false,
57 0,
58 complain_overflow_bitfield,
59 bfd_elf_generic_reloc,
ae1b99e4 60 "R_MN10300_NONE",
efc2b064
JL
61 false,
62 0,
63 0,
64 false),
207e944c 65 /* Standard 32 bit reloc. */
c3239e66
JL
66 HOWTO (R_MN10300_32,
67 0,
68 2,
69 32,
70 false,
71 0,
72 complain_overflow_bitfield,
73 bfd_elf_generic_reloc,
74 "R_MN10300_32",
d28f058e 75 false,
c3239e66
JL
76 0xffffffff,
77 0xffffffff,
78 false),
207e944c 79 /* Standard 16 bit reloc. */
c3239e66
JL
80 HOWTO (R_MN10300_16,
81 0,
82 1,
83 16,
84 false,
85 0,
86 complain_overflow_bitfield,
87 bfd_elf_generic_reloc,
88 "R_MN10300_16",
d28f058e 89 false,
c3239e66
JL
90 0xffff,
91 0xffff,
92 false),
207e944c 93 /* Standard 8 bit reloc. */
c3239e66
JL
94 HOWTO (R_MN10300_8,
95 0,
96 0,
97 8,
98 false,
99 0,
100 complain_overflow_bitfield,
101 bfd_elf_generic_reloc,
102 "R_MN10300_8",
d28f058e 103 false,
c3239e66
JL
104 0xff,
105 0xff,
106 false),
77bf22e6
JL
107 /* Standard 32bit pc-relative reloc. */
108 HOWTO (R_MN10300_PCREL32,
12fdaaf8
JL
109 0,
110 2,
111 32,
112 true,
113 0,
114 complain_overflow_bitfield,
77bf22e6
JL
115 bfd_elf_generic_reloc,
116 "R_MN10300_PCREL32",
117 false,
c3239e66
JL
118 0xffffffff,
119 0xffffffff,
77bf22e6
JL
120 true),
121 /* Standard 16bit pc-relative reloc. */
122 HOWTO (R_MN10300_PCREL16,
c3239e66
JL
123 0,
124 1,
125 16,
126 true,
127 0,
128 complain_overflow_bitfield,
77bf22e6
JL
129 bfd_elf_generic_reloc,
130 "R_MN10300_PCREL16",
131 false,
c3239e66
JL
132 0xffff,
133 0xffff,
77bf22e6
JL
134 true),
135 /* Standard 8 pc-relative reloc. */
136 HOWTO (R_MN10300_PCREL8,
c3239e66
JL
137 0,
138 0,
139 8,
140 true,
141 0,
142 complain_overflow_bitfield,
77bf22e6
JL
143 bfd_elf_generic_reloc,
144 "R_MN10300_PCREL8",
145 false,
c3239e66
JL
146 0xff,
147 0xff,
12fdaaf8 148 true),
efc2b064
JL
149};
150
ae1b99e4 151struct mn10300_reloc_map
efc2b064
JL
152{
153 unsigned char bfd_reloc_val;
154 unsigned char elf_reloc_val;
155};
156
ae1b99e4 157static const struct mn10300_reloc_map mn10300_reloc_map[] =
efc2b064 158{
ae1b99e4 159 { BFD_RELOC_NONE, R_MN10300_NONE, },
c3239e66
JL
160 { BFD_RELOC_32, R_MN10300_32, },
161 { BFD_RELOC_16, R_MN10300_16, },
162 { BFD_RELOC_8, R_MN10300_8, },
77bf22e6
JL
163 { BFD_RELOC_32_PCREL, R_MN10300_PCREL32, },
164 { BFD_RELOC_16_PCREL, R_MN10300_PCREL16, },
165 { BFD_RELOC_8_PCREL, R_MN10300_PCREL8, },
efc2b064
JL
166};
167
168static reloc_howto_type *
169bfd_elf32_bfd_reloc_type_lookup (abfd, code)
170 bfd *abfd;
171 bfd_reloc_code_real_type code;
172{
173 unsigned int i;
174
175 for (i = 0;
ae1b99e4 176 i < sizeof (mn10300_reloc_map) / sizeof (struct mn10300_reloc_map);
efc2b064
JL
177 i++)
178 {
ae1b99e4
JL
179 if (mn10300_reloc_map[i].bfd_reloc_val == code)
180 return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val];
efc2b064
JL
181 }
182
183 return NULL;
184}
185
12fdaaf8 186/* Set the howto pointer for an MN10300 ELF reloc. */
efc2b064
JL
187
188static void
943686fa 189mn10300_info_to_howto (abfd, cache_ptr, dst)
efc2b064
JL
190 bfd *abfd;
191 arelent *cache_ptr;
943686fa 192 Elf32_Internal_Rela *dst;
efc2b064
JL
193{
194 unsigned int r_type;
195
196 r_type = ELF32_R_TYPE (dst->r_info);
ae1b99e4
JL
197 BFD_ASSERT (r_type < (unsigned int) R_MN10300_MAX);
198 cache_ptr->howto = &elf_mn10300_howto_table[r_type];
efc2b064
JL
199}
200
5847e6dd
JL
201/* Perform a relocation as part of a final link. */
202static bfd_reloc_status_type
203mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
204 input_section, contents, offset, value,
205 addend, info, sym_sec, is_local)
206 reloc_howto_type *howto;
207 bfd *input_bfd;
208 bfd *output_bfd;
209 asection *input_section;
210 bfd_byte *contents;
211 bfd_vma offset;
212 bfd_vma value;
213 bfd_vma addend;
214 struct bfd_link_info *info;
215 asection *sym_sec;
216 int is_local;
217{
218 unsigned long r_type = howto->type;
219 bfd_byte *hit_data = contents + offset;
220
221 switch (r_type)
222 {
223
224 case R_MN10300_NONE:
225 return bfd_reloc_ok;
226
227 case R_MN10300_32:
228 value += addend;
229 bfd_put_32 (input_bfd, value, hit_data);
230 return bfd_reloc_ok;
231
232 case R_MN10300_16:
233 value += addend;
234
235 if ((long)value > 0x7fff || (long)value < -0x8000)
236 return bfd_reloc_overflow;
237
238 bfd_put_16 (input_bfd, value, hit_data);
239 return bfd_reloc_ok;
240
241 case R_MN10300_8:
242 value += addend;
243
244 if ((long)value > 0x7fff || (long)value < -0x8000)
245 return bfd_reloc_overflow;
246
247 bfd_put_8 (input_bfd, value, hit_data);
248 return bfd_reloc_ok;
249
250 case R_MN10300_PCREL8:
251 value -= (input_section->output_section->vma
252 + input_section->output_offset);
253 value -= offset;
254 value += addend;
255
256 if ((long)value > 0xff || (long)value < -0x100)
257 return bfd_reloc_overflow;
258
259 bfd_put_8 (input_bfd, value, hit_data);
260 return bfd_reloc_ok;
261
262 case R_MN10300_PCREL16:
263 value -= (input_section->output_section->vma
264 + input_section->output_offset);
265 value -= offset;
266 value += addend;
267
268 if ((long)value > 0xffff || (long)value < -0x10000)
269 return bfd_reloc_overflow;
270
271 bfd_put_16 (input_bfd, value, hit_data);
272 return bfd_reloc_ok;
273
274 case R_MN10300_PCREL32:
275 value -= (input_section->output_section->vma
276 + input_section->output_offset);
277 value -= offset;
278 value += addend;
279
280 bfd_put_32 (input_bfd, value, hit_data);
281 return bfd_reloc_ok;
282
283 default:
284 return bfd_reloc_notsupported;
285 }
286}
287
288\f
289/* Relocate an MN10300 ELF section. */
290static boolean
291mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
292 contents, relocs, local_syms, local_sections)
293 bfd *output_bfd;
294 struct bfd_link_info *info;
295 bfd *input_bfd;
296 asection *input_section;
297 bfd_byte *contents;
298 Elf_Internal_Rela *relocs;
299 Elf_Internal_Sym *local_syms;
300 asection **local_sections;
301{
302 Elf_Internal_Shdr *symtab_hdr;
303 struct elf_link_hash_entry **sym_hashes;
304 Elf_Internal_Rela *rel, *relend;
305
306 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
307 sym_hashes = elf_sym_hashes (input_bfd);
308
309 rel = relocs;
310 relend = relocs + input_section->reloc_count;
311 for (; rel < relend; rel++)
312 {
313 int r_type;
314 reloc_howto_type *howto;
315 unsigned long r_symndx;
316 Elf_Internal_Sym *sym;
317 asection *sec;
318 struct elf_link_hash_entry *h;
319 bfd_vma relocation;
320 bfd_reloc_status_type r;
321
322 r_symndx = ELF32_R_SYM (rel->r_info);
323 r_type = ELF32_R_TYPE (rel->r_info);
324 howto = elf_mn10300_howto_table + r_type;
325
326 if (info->relocateable)
327 {
328 /* This is a relocateable link. We don't have to change
329 anything, unless the reloc is against a section symbol,
330 in which case we have to adjust according to where the
331 section symbol winds up in the output section. */
332 if (r_symndx < symtab_hdr->sh_info)
333 {
334 sym = local_syms + r_symndx;
335 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
336 {
337 sec = local_sections[r_symndx];
338 rel->r_addend += sec->output_offset + sym->st_value;
339 }
340 }
341
342 continue;
343 }
344
345 /* This is a final link. */
346 h = NULL;
347 sym = NULL;
348 sec = NULL;
349 if (r_symndx < symtab_hdr->sh_info)
350 {
351 sym = local_syms + r_symndx;
352 sec = local_sections[r_symndx];
353 relocation = (sec->output_section->vma
354 + sec->output_offset
355 + sym->st_value);
356 }
357 else
358 {
359 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
360 while (h->root.type == bfd_link_hash_indirect
361 || h->root.type == bfd_link_hash_warning)
362 h = (struct elf_link_hash_entry *) h->root.u.i.link;
363 if (h->root.type == bfd_link_hash_defined
364 || h->root.type == bfd_link_hash_defweak)
365 {
366 sec = h->root.u.def.section;
367 relocation = (h->root.u.def.value
368 + sec->output_section->vma
369 + sec->output_offset);
370 }
371 else if (h->root.type == bfd_link_hash_undefweak)
372 relocation = 0;
373 else
374 {
375 if (! ((*info->callbacks->undefined_symbol)
376 (info, h->root.root.string, input_bfd,
377 input_section, rel->r_offset)))
378 return false;
379 relocation = 0;
380 }
381 }
382
383 r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
384 input_section,
385 contents, rel->r_offset,
386 relocation, rel->r_addend,
387 info, sec, h == NULL);
388
389 if (r != bfd_reloc_ok)
390 {
391 const char *name;
392 const char *msg = (const char *)0;
393
394 if (h != NULL)
395 name = h->root.root.string;
396 else
397 {
398 name = (bfd_elf_string_from_elf_section
399 (input_bfd, symtab_hdr->sh_link, sym->st_name));
400 if (name == NULL || *name == '\0')
401 name = bfd_section_name (input_bfd, sec);
402 }
403
404 switch (r)
405 {
406 case bfd_reloc_overflow:
407 if (! ((*info->callbacks->reloc_overflow)
408 (info, name, howto->name, (bfd_vma) 0,
409 input_bfd, input_section, rel->r_offset)))
410 return false;
411 break;
412
413 case bfd_reloc_undefined:
414 if (! ((*info->callbacks->undefined_symbol)
415 (info, name, input_bfd, input_section,
416 rel->r_offset)))
417 return false;
418 break;
419
420 case bfd_reloc_outofrange:
421 msg = "internal error: out of range error";
422 goto common_error;
423
424 case bfd_reloc_notsupported:
425 msg = "internal error: unsupported relocation error";
426 goto common_error;
427
428 case bfd_reloc_dangerous:
429 msg = "internal error: dangerous error";
430 goto common_error;
431
432 default:
433 msg = "internal error: unknown error";
434 /* fall through */
435
436 common_error:
437 if (!((*info->callbacks->warning)
438 (info, msg, name, input_bfd, input_section,
439 rel->r_offset)))
440 return false;
441 break;
442 }
443 }
444 }
445
446 return true;
447}
448
ae1b99e4
JL
449#define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec
450#define TARGET_LITTLE_NAME "elf32-mn10300"
451#define ELF_ARCH bfd_arch_mn10300
452#define ELF_MACHINE_CODE EM_CYGNUS_MN10300
efc2b064
JL
453#define ELF_MAXPAGESIZE 0x1000
454
943686fa
JL
455#define elf_info_to_howto mn10300_info_to_howto
456#define elf_info_to_howto_rel 0
5847e6dd 457#define elf_backend_relocate_section mn10300_elf_relocate_section
efc2b064 458
31cffd2e
JL
459#define elf_symbol_leading_char '_'
460
efc2b064 461#include "elf32-target.h"
This page took 0.055328 seconds and 4 git commands to generate.