elf32-d10v.c revision 1.1.1.6.2.2 1 1.1 skrll /* D10V-specific support for 32-bit ELF
2 1.1.1.6.2.2 martin Copyright (C) 1996-2020 Free Software Foundation, Inc.
3 1.1 skrll Contributed by Martin Hunt (hunt (at) cygnus.com).
4 1.1 skrll
5 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
6 1.1 skrll
7 1.1 skrll This program is free software; you can redistribute it and/or modify
8 1.1 skrll it under the terms of the GNU General Public License as published by
9 1.1 skrll the Free Software Foundation; either version 3 of the License, or
10 1.1 skrll (at your option) any later version.
11 1.1 skrll
12 1.1 skrll This program is distributed in the hope that it will be useful,
13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 skrll GNU General Public License for more details.
16 1.1 skrll
17 1.1 skrll You should have received a copy of the GNU General Public License
18 1.1 skrll along with this program; if not, write to the Free Software
19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 skrll MA 02110-1301, USA. */
21 1.1 skrll
22 1.1 skrll #include "sysdep.h"
23 1.1 skrll #include "bfd.h"
24 1.1 skrll #include "libbfd.h"
25 1.1 skrll #include "elf-bfd.h"
26 1.1 skrll #include "elf/d10v.h"
27 1.1 skrll
28 1.1 skrll /* Use REL instead of RELA to save space. */
29 1.1 skrll #define USE_REL 1
30 1.1 skrll
31 1.1 skrll static reloc_howto_type elf_d10v_howto_table[] =
32 1.1 skrll {
33 1.1 skrll /* This reloc does nothing. */
34 1.1 skrll HOWTO (R_D10V_NONE, /* Type. */
35 1.1 skrll 0, /* Rightshift. */
36 1.1.1.4 christos 3, /* Size (0 = byte, 1 = short, 2 = long). */
37 1.1.1.4 christos 0, /* Bitsize. */
38 1.1 skrll FALSE, /* PC_relative. */
39 1.1 skrll 0, /* Bitpos. */
40 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */
41 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
42 1.1 skrll "R_D10V_NONE", /* Name. */
43 1.1 skrll FALSE, /* Partial_inplace. */
44 1.1 skrll 0, /* Src_mask. */
45 1.1 skrll 0, /* Dst_mask. */
46 1.1 skrll FALSE), /* PCrel_offset. */
47 1.1 skrll
48 1.1 skrll /* An PC Relative 10-bit relocation, shifted by 2, right container. */
49 1.1 skrll HOWTO (R_D10V_10_PCREL_R, /* Type. */
50 1.1.1.6 christos 2, /* Rightshift. */
51 1.1.1.6 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
52 1.1.1.6 christos 8, /* Bitsize. */
53 1.1.1.6 christos TRUE, /* PC_relative. */
54 1.1.1.6 christos 0, /* Bitpos. */
55 1.1 skrll complain_overflow_signed, /* Complain_on_overflow. */
56 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
57 1.1 skrll "R_D10V_10_PCREL_R", /* Name. */
58 1.1.1.6 christos FALSE, /* Partial_inplace. */
59 1.1 skrll 0xff, /* Src_mask. */
60 1.1.1.6 christos 0xff, /* Dst_mask. */
61 1.1 skrll TRUE), /* PCrel_offset. */
62 1.1 skrll
63 1.1 skrll /* An PC Relative 10-bit relocation, shifted by 2, left container. */
64 1.1 skrll HOWTO (R_D10V_10_PCREL_L, /* Type. */
65 1.1.1.6 christos 2, /* Rightshift. */
66 1.1.1.6 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
67 1.1.1.6 christos 8, /* Bitsize. */
68 1.1.1.6 christos TRUE, /* PC_relative. */
69 1.1.1.6 christos 15, /* Bitpos. */
70 1.1 skrll complain_overflow_signed, /* Complain_on_overflow. */
71 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
72 1.1 skrll "R_D10V_10_PCREL_L", /* Name. */
73 1.1.1.6 christos FALSE, /* Partial_inplace. */
74 1.1 skrll 0x07f8000, /* Src_mask. */
75 1.1.1.6 christos 0x07f8000, /* Dst_mask. */
76 1.1 skrll TRUE), /* PCrel_offset. */
77 1.1 skrll
78 1.1 skrll /* A 16 bit absolute relocation. */
79 1.1 skrll HOWTO (R_D10V_16, /* Type. */
80 1.1 skrll 0, /* Rightshift. */
81 1.1 skrll 1, /* Size (0 = byte, 1 = short, 2 = long). */
82 1.1 skrll 16, /* Bitsize. */
83 1.1 skrll FALSE, /* PC_relative. */
84 1.1 skrll 0, /* Bitpos. */
85 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */
86 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
87 1.1 skrll "R_D10V_16", /* Name. */
88 1.1 skrll FALSE, /* Partial_inplace. */
89 1.1 skrll 0xffff, /* Src_mask. */
90 1.1 skrll 0xffff, /* Dst_mask. */
91 1.1 skrll FALSE), /* PCrel_offset. */
92 1.1 skrll
93 1.1 skrll /* An 18 bit absolute relocation, right shifted 2. */
94 1.1 skrll HOWTO (R_D10V_18, /* Type. */
95 1.1 skrll 2, /* Rightshift. */
96 1.1 skrll 1, /* Size (0 = byte, 1 = short, 2 = long). */
97 1.1 skrll 16, /* Bitsize. */
98 1.1 skrll FALSE, /* PC_relative. */
99 1.1 skrll 0, /* Bitpos. */
100 1.1 skrll complain_overflow_dont, /* Complain_on_overflow. */
101 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
102 1.1 skrll "R_D10V_18", /* Name. */
103 1.1 skrll FALSE, /* Partial_inplace. */
104 1.1 skrll 0xffff, /* Src_mask. */
105 1.1 skrll 0xffff, /* Dst_mask. */
106 1.1 skrll FALSE), /* PCrel_offset. */
107 1.1 skrll
108 1.1 skrll /* A relative 18 bit relocation, right shifted by 2. */
109 1.1 skrll HOWTO (R_D10V_18_PCREL, /* Type. */
110 1.1 skrll 2, /* Rightshift. */
111 1.1 skrll 2, /* Size (0 = byte, 1 = short, 2 = long). */
112 1.1 skrll 16, /* Bitsize. */
113 1.1 skrll TRUE, /* PC_relative. */
114 1.1 skrll 0, /* Bitpos. */
115 1.1 skrll complain_overflow_signed, /* Complain_on_overflow. */
116 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
117 1.1 skrll "R_D10V_18_PCREL", /* Name. */
118 1.1 skrll FALSE, /* Partial_inplace. */
119 1.1 skrll 0xffff, /* Src_mask. */
120 1.1 skrll 0xffff, /* Dst_mask. */
121 1.1 skrll TRUE), /* PCrel_offset. */
122 1.1 skrll
123 1.1 skrll /* A 32 bit absolute relocation. */
124 1.1 skrll HOWTO (R_D10V_32, /* Type. */
125 1.1 skrll 0, /* Rightshift. */
126 1.1 skrll 2, /* Size (0 = byte, 1 = short, 2 = long). */
127 1.1 skrll 32, /* Bitsize. */
128 1.1 skrll FALSE, /* PC_relative. */
129 1.1 skrll 0, /* Bitpos. */
130 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */
131 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */
132 1.1 skrll "R_D10V_32", /* Name. */
133 1.1 skrll FALSE, /* Partial_inplace. */
134 1.1 skrll 0xffffffff, /* Src_mask. */
135 1.1 skrll 0xffffffff, /* Dst_mask. */
136 1.1 skrll FALSE), /* PCrel_offset. */
137 1.1 skrll
138 1.1 skrll /* GNU extension to record C++ vtable hierarchy. */
139 1.1 skrll HOWTO (R_D10V_GNU_VTINHERIT, /* Type. */
140 1.1.1.6 christos 0, /* Rightshift. */
141 1.1.1.6 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
142 1.1.1.6 christos 0, /* Bitsize. */
143 1.1.1.6 christos FALSE, /* PC_relative. */
144 1.1.1.6 christos 0, /* Bitpos. */
145 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */
146 1.1.1.6 christos NULL, /* Special_function. */
147 1.1 skrll "R_D10V_GNU_VTINHERIT",/* Name. */
148 1.1.1.6 christos FALSE, /* Partial_inplace. */
149 1.1.1.6 christos 0, /* Src_mask. */
150 1.1.1.6 christos 0, /* Dst_mask. */
151 1.1.1.6 christos FALSE), /* PCrel_offset. */
152 1.1 skrll
153 1.1 skrll /* GNU extension to record C++ vtable member usage. */
154 1.1.1.6 christos HOWTO (R_D10V_GNU_VTENTRY, /* Type. */
155 1.1.1.6 christos 0, /* Rightshift. */
156 1.1.1.6 christos 2, /* Size (0 = byte, 1 = short, 2 = long). */
157 1.1.1.6 christos 0, /* Bitsize. */
158 1.1.1.6 christos FALSE, /* PC_relative. */
159 1.1.1.6 christos 0, /* Bitpos. */
160 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */
161 1.1 skrll _bfd_elf_rel_vtable_reloc_fn, /* Special_function. */
162 1.1.1.6 christos "R_D10V_GNU_VTENTRY", /* Name. */
163 1.1.1.6 christos FALSE, /* Partial_inplace. */
164 1.1.1.6 christos 0, /* Src_mask. */
165 1.1.1.6 christos 0, /* Dst_mask. */
166 1.1.1.6 christos FALSE), /* PCrel_offset. */
167 1.1 skrll };
168 1.1 skrll
169 1.1 skrll /* Map BFD reloc types to D10V ELF reloc types. */
170 1.1 skrll
171 1.1 skrll struct d10v_reloc_map
172 1.1 skrll {
173 1.1 skrll bfd_reloc_code_real_type bfd_reloc_val;
174 1.1 skrll unsigned char elf_reloc_val;
175 1.1 skrll };
176 1.1 skrll
177 1.1 skrll static const struct d10v_reloc_map d10v_reloc_map[] =
178 1.1 skrll {
179 1.1 skrll { BFD_RELOC_NONE, R_D10V_NONE, },
180 1.1 skrll { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
181 1.1 skrll { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
182 1.1 skrll { BFD_RELOC_16, R_D10V_16 },
183 1.1 skrll { BFD_RELOC_D10V_18, R_D10V_18 },
184 1.1 skrll { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
185 1.1 skrll { BFD_RELOC_32, R_D10V_32 },
186 1.1 skrll { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
187 1.1 skrll { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
188 1.1 skrll };
189 1.1 skrll
190 1.1 skrll static reloc_howto_type *
191 1.1 skrll bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
192 1.1 skrll bfd_reloc_code_real_type code)
193 1.1 skrll {
194 1.1 skrll unsigned int i;
195 1.1 skrll
196 1.1 skrll for (i = 0;
197 1.1 skrll i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map);
198 1.1 skrll i++)
199 1.1 skrll if (d10v_reloc_map[i].bfd_reloc_val == code)
200 1.1 skrll return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val];
201 1.1 skrll
202 1.1 skrll return NULL;
203 1.1 skrll }
204 1.1 skrll
205 1.1 skrll static reloc_howto_type *
206 1.1 skrll bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
207 1.1 skrll const char *r_name)
208 1.1 skrll {
209 1.1 skrll unsigned int i;
210 1.1 skrll
211 1.1 skrll for (i = 0;
212 1.1 skrll i < sizeof (elf_d10v_howto_table) / sizeof (elf_d10v_howto_table[0]);
213 1.1 skrll i++)
214 1.1 skrll if (elf_d10v_howto_table[i].name != NULL
215 1.1 skrll && strcasecmp (elf_d10v_howto_table[i].name, r_name) == 0)
216 1.1 skrll return &elf_d10v_howto_table[i];
217 1.1 skrll
218 1.1 skrll return NULL;
219 1.1 skrll }
220 1.1 skrll
221 1.1 skrll /* Set the howto pointer for an D10V ELF reloc. */
222 1.1 skrll
223 1.1.1.6.2.1 christos static bfd_boolean
224 1.1.1.6.2.1 christos d10v_info_to_howto_rel (bfd *abfd,
225 1.1 skrll arelent *cache_ptr,
226 1.1 skrll Elf_Internal_Rela *dst)
227 1.1 skrll {
228 1.1 skrll unsigned int r_type;
229 1.1 skrll
230 1.1 skrll r_type = ELF32_R_TYPE (dst->r_info);
231 1.1.1.4 christos if (r_type >= (unsigned int) R_D10V_max)
232 1.1.1.4 christos {
233 1.1.1.6 christos /* xgettext:c-format */
234 1.1.1.6.2.1 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
235 1.1.1.6.2.1 christos abfd, r_type);
236 1.1.1.6.2.1 christos bfd_set_error (bfd_error_bad_value);
237 1.1.1.6.2.1 christos return FALSE;
238 1.1.1.4 christos }
239 1.1 skrll cache_ptr->howto = &elf_d10v_howto_table[r_type];
240 1.1.1.6.2.1 christos return TRUE;
241 1.1 skrll }
242 1.1 skrll
243 1.1 skrll static asection *
244 1.1 skrll elf32_d10v_gc_mark_hook (asection *sec,
245 1.1 skrll struct bfd_link_info *info,
246 1.1 skrll Elf_Internal_Rela *rel,
247 1.1 skrll struct elf_link_hash_entry *h,
248 1.1 skrll Elf_Internal_Sym *sym)
249 1.1 skrll {
250 1.1 skrll if (h != NULL)
251 1.1 skrll switch (ELF32_R_TYPE (rel->r_info))
252 1.1 skrll {
253 1.1 skrll case R_D10V_GNU_VTINHERIT:
254 1.1 skrll case R_D10V_GNU_VTENTRY:
255 1.1 skrll return NULL;
256 1.1 skrll }
257 1.1 skrll
258 1.1 skrll return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
259 1.1 skrll }
260 1.1 skrll
261 1.1 skrll /* Look through the relocs for a section during the first phase.
262 1.1 skrll Since we don't do .gots or .plts, we just need to consider the
263 1.1 skrll virtual table relocs for gc. */
264 1.1 skrll
265 1.1 skrll static bfd_boolean
266 1.1 skrll elf32_d10v_check_relocs (bfd *abfd,
267 1.1 skrll struct bfd_link_info *info,
268 1.1 skrll asection *sec,
269 1.1 skrll const Elf_Internal_Rela *relocs)
270 1.1 skrll {
271 1.1 skrll Elf_Internal_Shdr *symtab_hdr;
272 1.1 skrll struct elf_link_hash_entry **sym_hashes;
273 1.1 skrll const Elf_Internal_Rela *rel;
274 1.1 skrll const Elf_Internal_Rela *rel_end;
275 1.1 skrll
276 1.1.1.4 christos if (bfd_link_relocatable (info))
277 1.1 skrll return TRUE;
278 1.1 skrll
279 1.1 skrll symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
280 1.1 skrll sym_hashes = elf_sym_hashes (abfd);
281 1.1 skrll
282 1.1 skrll rel_end = relocs + sec->reloc_count;
283 1.1 skrll for (rel = relocs; rel < rel_end; rel++)
284 1.1 skrll {
285 1.1 skrll struct elf_link_hash_entry *h;
286 1.1 skrll unsigned long r_symndx;
287 1.1 skrll
288 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info);
289 1.1 skrll if (r_symndx < symtab_hdr->sh_info)
290 1.1.1.6 christos h = NULL;
291 1.1 skrll else
292 1.1 skrll {
293 1.1 skrll h = sym_hashes[r_symndx - symtab_hdr->sh_info];
294 1.1 skrll while (h->root.type == bfd_link_hash_indirect
295 1.1 skrll || h->root.type == bfd_link_hash_warning)
296 1.1 skrll h = (struct elf_link_hash_entry *) h->root.u.i.link;
297 1.1 skrll }
298 1.1 skrll
299 1.1 skrll switch (ELF32_R_TYPE (rel->r_info))
300 1.1.1.6 christos {
301 1.1.1.6 christos /* This relocation describes the C++ object vtable hierarchy.
302 1.1.1.6 christos Reconstruct it for later use during GC. */
303 1.1.1.6 christos case R_D10V_GNU_VTINHERIT:
304 1.1.1.6 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
305 1.1.1.6 christos return FALSE;
306 1.1.1.6 christos break;
307 1.1.1.6 christos
308 1.1.1.6 christos /* This relocation describes which C++ vtable entries are actually
309 1.1.1.6 christos used. Record for later use during GC. */
310 1.1.1.6 christos case R_D10V_GNU_VTENTRY:
311 1.1.1.6.2.2 martin if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
312 1.1.1.6 christos return FALSE;
313 1.1.1.6 christos break;
314 1.1.1.6 christos }
315 1.1 skrll }
316 1.1 skrll
317 1.1 skrll return TRUE;
318 1.1 skrll }
319 1.1 skrll
320 1.1 skrll static bfd_vma
321 1.1 skrll extract_rel_addend (bfd *abfd,
322 1.1 skrll bfd_byte *where,
323 1.1 skrll reloc_howto_type *howto)
324 1.1 skrll {
325 1.1 skrll bfd_vma insn, val;
326 1.1 skrll
327 1.1 skrll switch (howto->size)
328 1.1 skrll {
329 1.1 skrll case 0:
330 1.1 skrll insn = bfd_get_8 (abfd, where);
331 1.1 skrll break;
332 1.1 skrll case 1:
333 1.1 skrll insn = bfd_get_16 (abfd, where);
334 1.1 skrll break;
335 1.1 skrll case 2:
336 1.1 skrll insn = bfd_get_32 (abfd, where);
337 1.1 skrll break;
338 1.1 skrll default:
339 1.1 skrll abort ();
340 1.1 skrll }
341 1.1 skrll
342 1.1 skrll val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
343 1.1 skrll /* We should really be testing for signed addends here, but we don't
344 1.1 skrll have that info directly in the howto. */
345 1.1 skrll if (howto->pc_relative)
346 1.1 skrll {
347 1.1 skrll bfd_vma sign;
348 1.1 skrll sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
349 1.1 skrll sign = sign >> howto->bitpos << howto->rightshift;
350 1.1 skrll val = (val ^ sign) - sign;
351 1.1 skrll }
352 1.1 skrll return val;
353 1.1 skrll }
354 1.1 skrll
355 1.1 skrll static void
356 1.1 skrll insert_rel_addend (bfd *abfd,
357 1.1 skrll bfd_byte *where,
358 1.1 skrll reloc_howto_type *howto,
359 1.1 skrll bfd_vma addend)
360 1.1 skrll {
361 1.1 skrll bfd_vma insn;
362 1.1 skrll
363 1.1 skrll addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
364 1.1 skrll insn = ~howto->dst_mask;
365 1.1 skrll switch (howto->size)
366 1.1 skrll {
367 1.1 skrll case 0:
368 1.1 skrll insn &= bfd_get_8 (abfd, where);
369 1.1 skrll insn |= addend;
370 1.1 skrll bfd_put_8 (abfd, insn, where);
371 1.1 skrll break;
372 1.1 skrll case 1:
373 1.1 skrll insn &= bfd_get_16 (abfd, where);
374 1.1 skrll insn |= addend;
375 1.1 skrll bfd_put_16 (abfd, insn, where);
376 1.1 skrll break;
377 1.1 skrll case 2:
378 1.1 skrll insn &= bfd_get_32 (abfd, where);
379 1.1 skrll insn |= addend;
380 1.1 skrll bfd_put_32 (abfd, insn, where);
381 1.1 skrll break;
382 1.1 skrll default:
383 1.1 skrll abort ();
384 1.1 skrll }
385 1.1 skrll }
386 1.1 skrll
387 1.1 skrll /* Relocate a D10V ELF section. */
388 1.1 skrll
389 1.1 skrll static bfd_boolean
390 1.1 skrll elf32_d10v_relocate_section (bfd *output_bfd,
391 1.1 skrll struct bfd_link_info *info,
392 1.1 skrll bfd *input_bfd,
393 1.1 skrll asection *input_section,
394 1.1 skrll bfd_byte *contents,
395 1.1 skrll Elf_Internal_Rela *relocs,
396 1.1 skrll Elf_Internal_Sym *local_syms,
397 1.1 skrll asection **local_sections)
398 1.1 skrll {
399 1.1 skrll Elf_Internal_Shdr *symtab_hdr;
400 1.1 skrll struct elf_link_hash_entry **sym_hashes;
401 1.1 skrll Elf_Internal_Rela *rel, *relend;
402 1.1 skrll const char *name;
403 1.1 skrll
404 1.1 skrll symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
405 1.1 skrll sym_hashes = elf_sym_hashes (input_bfd);
406 1.1 skrll
407 1.1 skrll rel = relocs;
408 1.1 skrll relend = relocs + input_section->reloc_count;
409 1.1 skrll for (; rel < relend; rel++)
410 1.1 skrll {
411 1.1 skrll int r_type;
412 1.1 skrll reloc_howto_type *howto;
413 1.1 skrll unsigned long r_symndx;
414 1.1 skrll Elf_Internal_Sym *sym;
415 1.1 skrll asection *sec;
416 1.1 skrll struct elf_link_hash_entry *h;
417 1.1 skrll bfd_vma relocation;
418 1.1 skrll bfd_reloc_status_type r;
419 1.1 skrll
420 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info);
421 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info);
422 1.1 skrll
423 1.1 skrll if (r_type == R_D10V_GNU_VTENTRY
424 1.1.1.6 christos || r_type == R_D10V_GNU_VTINHERIT)
425 1.1.1.6 christos continue;
426 1.1 skrll
427 1.1 skrll howto = elf_d10v_howto_table + r_type;
428 1.1 skrll h = NULL;
429 1.1 skrll sym = NULL;
430 1.1 skrll sec = NULL;
431 1.1 skrll if (r_symndx < symtab_hdr->sh_info)
432 1.1 skrll {
433 1.1 skrll sym = local_syms + r_symndx;
434 1.1 skrll sec = local_sections[r_symndx];
435 1.1 skrll relocation = (sec->output_section->vma
436 1.1 skrll + sec->output_offset
437 1.1 skrll + sym->st_value);
438 1.1 skrll if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
439 1.1 skrll && ((sec->flags & SEC_MERGE) != 0
440 1.1.1.4 christos || (bfd_link_relocatable (info)
441 1.1 skrll && sec->output_offset != 0)))
442 1.1 skrll {
443 1.1 skrll bfd_vma addend;
444 1.1 skrll bfd_byte *where = contents + rel->r_offset;
445 1.1 skrll
446 1.1 skrll addend = extract_rel_addend (input_bfd, where, howto);
447 1.1 skrll
448 1.1.1.4 christos if (bfd_link_relocatable (info))
449 1.1 skrll addend += sec->output_offset;
450 1.1 skrll else
451 1.1 skrll {
452 1.1 skrll asection *msec = sec;
453 1.1 skrll addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
454 1.1 skrll addend);
455 1.1 skrll addend -= relocation;
456 1.1 skrll addend += msec->output_section->vma + msec->output_offset;
457 1.1 skrll }
458 1.1 skrll insert_rel_addend (input_bfd, where, howto, addend);
459 1.1 skrll }
460 1.1 skrll }
461 1.1 skrll else
462 1.1 skrll {
463 1.1.1.4 christos bfd_boolean unresolved_reloc, warned, ignored;
464 1.1 skrll
465 1.1 skrll RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
466 1.1 skrll r_symndx, symtab_hdr, sym_hashes,
467 1.1 skrll h, sec, relocation,
468 1.1.1.4 christos unresolved_reloc, warned, ignored);
469 1.1 skrll }
470 1.1 skrll
471 1.1.1.3 christos if (sec != NULL && discarded_section (sec))
472 1.1.1.2 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
473 1.1.1.3 christos rel, 1, relend, howto, 0, contents);
474 1.1 skrll
475 1.1.1.4 christos if (bfd_link_relocatable (info))
476 1.1 skrll continue;
477 1.1 skrll
478 1.1 skrll if (h != NULL)
479 1.1 skrll name = h->root.root.string;
480 1.1 skrll else
481 1.1 skrll {
482 1.1 skrll name = (bfd_elf_string_from_elf_section
483 1.1 skrll (input_bfd, symtab_hdr->sh_link, sym->st_name));
484 1.1 skrll if (name == NULL || *name == '\0')
485 1.1.1.6.2.2 martin name = bfd_section_name (sec);
486 1.1 skrll }
487 1.1 skrll
488 1.1 skrll r = _bfd_final_link_relocate (howto, input_bfd, input_section,
489 1.1.1.6 christos contents, rel->r_offset,
490 1.1.1.6 christos relocation, (bfd_vma) 0);
491 1.1 skrll
492 1.1 skrll if (r != bfd_reloc_ok)
493 1.1 skrll {
494 1.1 skrll const char * msg = (const char *) 0;
495 1.1 skrll
496 1.1 skrll switch (r)
497 1.1 skrll {
498 1.1 skrll case bfd_reloc_overflow:
499 1.1.1.5 christos (*info->callbacks->reloc_overflow)
500 1.1.1.5 christos (info, (h ? &h->root : NULL), name, howto->name,
501 1.1.1.5 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
502 1.1 skrll break;
503 1.1 skrll
504 1.1 skrll case bfd_reloc_undefined:
505 1.1.1.5 christos (*info->callbacks->undefined_symbol)
506 1.1.1.5 christos (info, name, input_bfd, input_section, rel->r_offset, TRUE);
507 1.1 skrll break;
508 1.1 skrll
509 1.1 skrll case bfd_reloc_outofrange:
510 1.1 skrll msg = _("internal error: out of range error");
511 1.1 skrll goto common_error;
512 1.1 skrll
513 1.1 skrll case bfd_reloc_notsupported:
514 1.1 skrll msg = _("internal error: unsupported relocation error");
515 1.1 skrll goto common_error;
516 1.1 skrll
517 1.1 skrll case bfd_reloc_dangerous:
518 1.1 skrll msg = _("internal error: dangerous error");
519 1.1 skrll goto common_error;
520 1.1 skrll
521 1.1 skrll default:
522 1.1 skrll msg = _("internal error: unknown error");
523 1.1 skrll /* fall through */
524 1.1 skrll
525 1.1 skrll common_error:
526 1.1.1.5 christos (*info->callbacks->warning) (info, msg, name, input_bfd,
527 1.1.1.5 christos input_section, rel->r_offset);
528 1.1 skrll break;
529 1.1 skrll }
530 1.1 skrll }
531 1.1 skrll }
532 1.1 skrll
533 1.1 skrll return TRUE;
534 1.1 skrll }
535 1.1 skrll #define ELF_ARCH bfd_arch_d10v
536 1.1 skrll #define ELF_MACHINE_CODE EM_D10V
537 1.1 skrll #define ELF_MACHINE_ALT1 EM_CYGNUS_D10V
538 1.1 skrll #define ELF_MAXPAGESIZE 0x1000
539 1.1 skrll
540 1.1.1.6 christos #define TARGET_BIG_SYM d10v_elf32_vec
541 1.1 skrll #define TARGET_BIG_NAME "elf32-d10v"
542 1.1 skrll
543 1.1.1.6.2.1 christos #define elf_info_to_howto NULL
544 1.1.1.6 christos #define elf_info_to_howto_rel d10v_info_to_howto_rel
545 1.1.1.6 christos #define elf_backend_object_p 0
546 1.1.1.6 christos #define elf_backend_gc_mark_hook elf32_d10v_gc_mark_hook
547 1.1.1.6 christos #define elf_backend_check_relocs elf32_d10v_check_relocs
548 1.1.1.6 christos #define elf_backend_relocate_section elf32_d10v_relocate_section
549 1.1.1.6 christos #define elf_backend_can_gc_sections 1
550 1.1 skrll
551 1.1 skrll #include "elf32-target.h"
552