* libbfd.c: Patch up the mmap code so that it is only built if BFD
[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_PCREL32_1BYTE,
44 R_MN10300_PCREL16_1BYTE,
45 R_MN10300_PCREL8_1BYTE,
46 R_MN10300_PCREL32_2BYTE,
47 R_MN10300_PCREL16_2BYTE,
48 R_MN10300_MAX
49 };
50
51 static reloc_howto_type elf_mn10300_howto_table[] =
52 {
53 /* Dummy relocation. Does nothing. */
54 HOWTO (R_MN10300_NONE,
55 0,
56 2,
57 16,
58 false,
59 0,
60 complain_overflow_bitfield,
61 bfd_elf_generic_reloc,
62 "R_MN10300_NONE",
63 false,
64 0,
65 0,
66 false),
67 /* Standard 32 bit reloc. */
68 HOWTO (R_MN10300_32,
69 0,
70 2,
71 32,
72 false,
73 0,
74 complain_overflow_bitfield,
75 bfd_elf_generic_reloc,
76 "R_MN10300_32",
77 false,
78 0xffffffff,
79 0xffffffff,
80 false),
81 /* Standard 16 bit reloc. */
82 HOWTO (R_MN10300_16,
83 0,
84 1,
85 16,
86 false,
87 0,
88 complain_overflow_bitfield,
89 bfd_elf_generic_reloc,
90 "R_MN10300_16",
91 false,
92 0xffff,
93 0xffff,
94 false),
95 /* Standard 8 bit reloc. */
96 HOWTO (R_MN10300_8,
97 0,
98 0,
99 8,
100 false,
101 0,
102 complain_overflow_bitfield,
103 bfd_elf_generic_reloc,
104 "R_MN10300_8",
105 false,
106 0xff,
107 0xff,
108 false),
109 /* Simple 32bit pc-relative reloc with a 1 byte adjustment
110 to get the pc-relative offset correct. */
111 HOWTO (R_MN10300_PCREL32_1BYTE,
112 0,
113 2,
114 32,
115 true,
116 0,
117 complain_overflow_bitfield,
118 bfd_elf32_mn10300_reloc,
119 "R_MN10300_PCREL32_1BYTE",
120 true,
121 0xffffffff,
122 0xffffffff,
123 false),
124 /* Simple 16bit pc-relative reloc with a 1 byte adjustment
125 to get the pc-relative offset correct. */
126 HOWTO (R_MN10300_PCREL16_1BYTE,
127 0,
128 1,
129 16,
130 true,
131 0,
132 complain_overflow_bitfield,
133 bfd_elf32_mn10300_reloc,
134 "R_MN10300_PCREL16_1BYTE",
135 true,
136 0xffff,
137 0xffff,
138 false),
139 /* Simple 8 pc-relative reloc with a 1 byte adjustment
140 to get the pc-relative offset correct. */
141 HOWTO (R_MN10300_PCREL8_1BYTE,
142 0,
143 0,
144 8,
145 true,
146 0,
147 complain_overflow_bitfield,
148 bfd_elf32_mn10300_reloc,
149 "R_MN10300_PCREL8_1BYTE",
150 true,
151 0xff,
152 0xff,
153 true),
154 /* Simple 32 pc-relative reloc with a 2 byte adjustment
155 to get the pc-relative offset correct. */
156 HOWTO (R_MN10300_PCREL32_2BYTE,
157 0,
158 2,
159 32,
160 true,
161 0,
162 complain_overflow_bitfield,
163 bfd_elf32_mn10300_reloc,
164 "R_MN10300_PCREL32_2BYTE",
165 true,
166 0xffffffff,
167 0xffffffff,
168 true),
169 /* Simple 16 pc-relative reloc with a 2 byte adjustment
170 to get the pc-relative offset correct. */
171 HOWTO (R_MN10300_PCREL16_2BYTE,
172 0,
173 1,
174 16,
175 true,
176 0,
177 complain_overflow_bitfield,
178 bfd_elf32_mn10300_reloc,
179 "R_MN10300_PCREL16_2BYTE",
180 true,
181 0xffff,
182 0xffff,
183 true),
184 };
185
186 struct mn10300_reloc_map
187 {
188 unsigned char bfd_reloc_val;
189 unsigned char elf_reloc_val;
190 };
191
192 static const struct mn10300_reloc_map mn10300_reloc_map[] =
193 {
194 { BFD_RELOC_NONE, R_MN10300_NONE, },
195 { BFD_RELOC_32, R_MN10300_32, },
196 { BFD_RELOC_16, R_MN10300_16, },
197 { BFD_RELOC_8, R_MN10300_8, },
198 { BFD_RELOC_32_PCREL, R_MN10300_PCREL32_1BYTE, },
199 { BFD_RELOC_16_PCREL, R_MN10300_PCREL16_1BYTE, },
200 { BFD_RELOC_8_PCREL, R_MN10300_PCREL8_1BYTE, },
201 { BFD_RELOC_MN10300_32_PCREL, R_MN10300_PCREL32_2BYTE, },
202 { BFD_RELOC_MN10300_16_PCREL, R_MN10300_PCREL16_2BYTE, },
203 };
204
205 static reloc_howto_type *
206 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
207 bfd *abfd;
208 bfd_reloc_code_real_type code;
209 {
210 unsigned int i;
211
212 for (i = 0;
213 i < sizeof (mn10300_reloc_map) / sizeof (struct mn10300_reloc_map);
214 i++)
215 {
216 if (mn10300_reloc_map[i].bfd_reloc_val == code)
217 return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val];
218 }
219
220 return NULL;
221 }
222
223 /* Set the howto pointer for an MN10300 ELF reloc. */
224
225 static void
226 mn10300_info_to_howto (abfd, cache_ptr, dst)
227 bfd *abfd;
228 arelent *cache_ptr;
229 Elf32_Internal_Rela *dst;
230 {
231 unsigned int r_type;
232
233 r_type = ELF32_R_TYPE (dst->r_info);
234 BFD_ASSERT (r_type < (unsigned int) R_MN10300_MAX);
235 cache_ptr->howto = &elf_mn10300_howto_table[r_type];
236 }
237
238 static bfd_reloc_status_type
239 bfd_elf32_mn10300_reloc (abfd, reloc, symbol, data, isection, obfd, err)
240 bfd *abfd;
241 arelent *reloc;
242 asymbol *symbol;
243 PTR data;
244 asection *isection;
245 bfd *obfd;
246 char **err;
247 {
248 if (obfd != (bfd *) NULL
249 && (symbol->flags & BSF_SECTION_SYM) == 0
250 && (! reloc->howto->partial_inplace
251 || reloc->addend == 0))
252 {
253 reloc->address += isection->output_offset;
254 return bfd_reloc_ok;
255 }
256 else if (obfd != NULL)
257 {
258 return bfd_reloc_continue;
259 }
260
261 /* Catch relocs involving undefined symbols. */
262 if (bfd_is_und_section (symbol->section)
263 && (symbol->flags & BSF_WEAK) == 0
264 && obfd == NULL)
265 return bfd_reloc_undefined;
266
267 /* We handle final linking of some relocs ourselves. */
268 {
269 long relocation;
270
271 /* Is the address of the relocation really within the section? */
272 if (reloc->address > isection->_cooked_size)
273 return bfd_reloc_outofrange;
274
275 /* Work out which section the relocation is targetted at and the
276 initial relocation command value. */
277
278 /* Get symbol value. (Common symbols are special.) */
279 if (bfd_is_com_section (symbol->section))
280 relocation = 0;
281 else
282 relocation = symbol->value;
283
284 /* Convert input-section-relative symbol value to absolute + addend. */
285 relocation += symbol->section->output_section->vma;
286 relocation += symbol->section->output_offset;
287 relocation += reloc->addend;
288
289 if (reloc->howto->pc_relative == true)
290 {
291 /* Here the variable relocation holds the final address of the
292 symbol we are relocating against, plus any addend. */
293 relocation -= isection->output_section->vma + isection->output_offset;
294
295 /* Deal with pcrel_offset */
296 relocation -= reloc->address;
297
298 if (reloc->howto->type == R_MN10300_PCREL32_1BYTE
299 || reloc->howto->type == R_MN10300_PCREL16_1BYTE
300 || reloc->howto->type == R_MN10300_PCREL8_1BYTE)
301 relocation += 1;
302 else if (reloc->howto->type == R_MN10300_PCREL32_2BYTE
303 || reloc->howto->type == R_MN10300_PCREL16_2BYTE)
304 relocation += 2;
305 }
306
307 /* I've got no clue... */
308 reloc->addend = 0;
309
310 if (reloc->howto->size == 0)
311 {
312 if (relocation > 0x7f || relocation < -0x80)
313 return bfd_reloc_overflow;
314
315 bfd_put_8 (abfd, relocation & 0xff,
316 (bfd_byte *)data + reloc->address);
317 }
318 else if (reloc->howto->size == 1)
319 {
320 if (relocation > 0x7fff || relocation < -0x8000)
321 return bfd_reloc_overflow;
322
323 bfd_put_16 (abfd, relocation & 0xffff,
324 (bfd_byte *)data + reloc->address);
325 }
326 else if (reloc->howto->size == 2)
327 bfd_put_32 (abfd, relocation, (bfd_byte *)data + reloc->address);
328 return bfd_reloc_ok;
329 }
330
331 return bfd_reloc_continue;
332 }
333
334 #define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec
335 #define TARGET_LITTLE_NAME "elf32-mn10300"
336 #define ELF_ARCH bfd_arch_mn10300
337 #define ELF_MACHINE_CODE EM_CYGNUS_MN10300
338 #define ELF_MAXPAGESIZE 0x1000
339
340 #define elf_info_to_howto mn10300_info_to_howto
341 #define elf_info_to_howto_rel 0
342
343 #define elf_symbol_leading_char '_'
344
345 #include "elf32-target.h"
This page took 0.036963 seconds and 4 git commands to generate.