elf32-d10v.c revision 1.1.1.4 1 1.1 skrll /* D10V-specific support for 32-bit ELF
2 1.1.1.4 christos Copyright (C) 1996-2015 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 skrll 2, /* Rightshift. */
51 1.1 skrll 2, /* Size (0 = byte, 1 = short, 2 = long). */
52 1.1 skrll 8, /* Bitsize. */
53 1.1 skrll TRUE, /* PC_relative. */
54 1.1 skrll 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 skrll FALSE, /* Partial_inplace. */
59 1.1 skrll 0xff, /* Src_mask. */
60 1.1 skrll 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 skrll 2, /* Rightshift. */
66 1.1 skrll 2, /* Size (0 = byte, 1 = short, 2 = long). */
67 1.1 skrll 8, /* Bitsize. */
68 1.1 skrll TRUE, /* PC_relative. */
69 1.1 skrll 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 skrll FALSE, /* Partial_inplace. */
74 1.1 skrll 0x07f8000, /* Src_mask. */
75 1.1 skrll 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 skrll 0, /* Rightshift. */
141 1.1 skrll 2, /* Size (0 = byte, 1 = short, 2 = long). */
142 1.1 skrll 0, /* Bitsize. */
143 1.1 skrll FALSE, /* PC_relative. */
144 1.1 skrll 0, /* Bitpos. */
145 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */
146 1.1 skrll NULL, /* Special_function. */
147 1.1 skrll "R_D10V_GNU_VTINHERIT",/* Name. */
148 1.1 skrll FALSE, /* Partial_inplace. */
149 1.1 skrll 0, /* Src_mask. */
150 1.1 skrll 0, /* Dst_mask. */
151 1.1 skrll FALSE), /* PCrel_offset. */
152 1.1 skrll
153 1.1 skrll /* GNU extension to record C++ vtable member usage. */
154 1.1 skrll HOWTO (R_D10V_GNU_VTENTRY, /* Type. */
155 1.1 skrll 0, /* Rightshift. */
156 1.1 skrll 2, /* Size (0 = byte, 1 = short, 2 = long). */
157 1.1 skrll 0, /* Bitsize. */
158 1.1 skrll FALSE, /* PC_relative. */
159 1.1 skrll 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 skrll "R_D10V_GNU_VTENTRY", /* Name. */
163 1.1 skrll FALSE, /* Partial_inplace. */
164 1.1 skrll 0, /* Src_mask. */
165 1.1 skrll 0, /* Dst_mask. */
166 1.1 skrll 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 skrll static void
224 1.1 skrll d10v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
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.4 christos _bfd_error_handler (_("%B: invalid D10V reloc number: %d"), abfd, r_type);
234 1.1.1.4 christos r_type = 0;
235 1.1.1.4 christos }
236 1.1 skrll cache_ptr->howto = &elf_d10v_howto_table[r_type];
237 1.1 skrll }
238 1.1 skrll
239 1.1 skrll static asection *
240 1.1 skrll elf32_d10v_gc_mark_hook (asection *sec,
241 1.1 skrll struct bfd_link_info *info,
242 1.1 skrll Elf_Internal_Rela *rel,
243 1.1 skrll struct elf_link_hash_entry *h,
244 1.1 skrll Elf_Internal_Sym *sym)
245 1.1 skrll {
246 1.1 skrll if (h != NULL)
247 1.1 skrll switch (ELF32_R_TYPE (rel->r_info))
248 1.1 skrll {
249 1.1 skrll case R_D10V_GNU_VTINHERIT:
250 1.1 skrll case R_D10V_GNU_VTENTRY:
251 1.1 skrll return NULL;
252 1.1 skrll }
253 1.1 skrll
254 1.1 skrll return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
255 1.1 skrll }
256 1.1 skrll
257 1.1 skrll /* Look through the relocs for a section during the first phase.
258 1.1 skrll Since we don't do .gots or .plts, we just need to consider the
259 1.1 skrll virtual table relocs for gc. */
260 1.1 skrll
261 1.1 skrll static bfd_boolean
262 1.1 skrll elf32_d10v_check_relocs (bfd *abfd,
263 1.1 skrll struct bfd_link_info *info,
264 1.1 skrll asection *sec,
265 1.1 skrll const Elf_Internal_Rela *relocs)
266 1.1 skrll {
267 1.1 skrll Elf_Internal_Shdr *symtab_hdr;
268 1.1 skrll struct elf_link_hash_entry **sym_hashes;
269 1.1 skrll const Elf_Internal_Rela *rel;
270 1.1 skrll const Elf_Internal_Rela *rel_end;
271 1.1 skrll
272 1.1.1.4 christos if (bfd_link_relocatable (info))
273 1.1 skrll return TRUE;
274 1.1 skrll
275 1.1 skrll symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
276 1.1 skrll sym_hashes = elf_sym_hashes (abfd);
277 1.1 skrll
278 1.1 skrll rel_end = relocs + sec->reloc_count;
279 1.1 skrll for (rel = relocs; rel < rel_end; rel++)
280 1.1 skrll {
281 1.1 skrll struct elf_link_hash_entry *h;
282 1.1 skrll unsigned long r_symndx;
283 1.1 skrll
284 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info);
285 1.1 skrll if (r_symndx < symtab_hdr->sh_info)
286 1.1 skrll h = NULL;
287 1.1 skrll else
288 1.1 skrll {
289 1.1 skrll h = sym_hashes[r_symndx - symtab_hdr->sh_info];
290 1.1 skrll while (h->root.type == bfd_link_hash_indirect
291 1.1 skrll || h->root.type == bfd_link_hash_warning)
292 1.1 skrll h = (struct elf_link_hash_entry *) h->root.u.i.link;
293 1.1.1.4 christos
294 1.1.1.4 christos /* PR15323, ref flags aren't set for references in the same
295 1.1.1.4 christos object. */
296 1.1.1.4 christos h->root.non_ir_ref = 1;
297 1.1 skrll }
298 1.1 skrll
299 1.1 skrll switch (ELF32_R_TYPE (rel->r_info))
300 1.1 skrll {
301 1.1 skrll /* This relocation describes the C++ object vtable hierarchy.
302 1.1 skrll Reconstruct it for later use during GC. */
303 1.1 skrll case R_D10V_GNU_VTINHERIT:
304 1.1 skrll if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
305 1.1 skrll return FALSE;
306 1.1 skrll break;
307 1.1 skrll
308 1.1 skrll /* This relocation describes which C++ vtable entries are actually
309 1.1 skrll used. Record for later use during GC. */
310 1.1 skrll case R_D10V_GNU_VTENTRY:
311 1.1 skrll BFD_ASSERT (h != NULL);
312 1.1 skrll if (h != NULL
313 1.1 skrll && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
314 1.1 skrll return FALSE;
315 1.1 skrll break;
316 1.1 skrll }
317 1.1 skrll }
318 1.1 skrll
319 1.1 skrll return TRUE;
320 1.1 skrll }
321 1.1 skrll
322 1.1 skrll static bfd_vma
323 1.1 skrll extract_rel_addend (bfd *abfd,
324 1.1 skrll bfd_byte *where,
325 1.1 skrll reloc_howto_type *howto)
326 1.1 skrll {
327 1.1 skrll bfd_vma insn, val;
328 1.1 skrll
329 1.1 skrll switch (howto->size)
330 1.1 skrll {
331 1.1 skrll case 0:
332 1.1 skrll insn = bfd_get_8 (abfd, where);
333 1.1 skrll break;
334 1.1 skrll case 1:
335 1.1 skrll insn = bfd_get_16 (abfd, where);
336 1.1 skrll break;
337 1.1 skrll case 2:
338 1.1 skrll insn = bfd_get_32 (abfd, where);
339 1.1 skrll break;
340 1.1 skrll default:
341 1.1 skrll abort ();
342 1.1 skrll }
343 1.1 skrll
344 1.1 skrll val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
345 1.1 skrll /* We should really be testing for signed addends here, but we don't
346 1.1 skrll have that info directly in the howto. */
347 1.1 skrll if (howto->pc_relative)
348 1.1 skrll {
349 1.1 skrll bfd_vma sign;
350 1.1 skrll sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
351 1.1 skrll sign = sign >> howto->bitpos << howto->rightshift;
352 1.1 skrll val = (val ^ sign) - sign;
353 1.1 skrll }
354 1.1 skrll return val;
355 1.1 skrll }
356 1.1 skrll
357 1.1 skrll static void
358 1.1 skrll insert_rel_addend (bfd *abfd,
359 1.1 skrll bfd_byte *where,
360 1.1 skrll reloc_howto_type *howto,
361 1.1 skrll bfd_vma addend)
362 1.1 skrll {
363 1.1 skrll bfd_vma insn;
364 1.1 skrll
365 1.1 skrll addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
366 1.1 skrll insn = ~howto->dst_mask;
367 1.1 skrll switch (howto->size)
368 1.1 skrll {
369 1.1 skrll case 0:
370 1.1 skrll insn &= bfd_get_8 (abfd, where);
371 1.1 skrll insn |= addend;
372 1.1 skrll bfd_put_8 (abfd, insn, where);
373 1.1 skrll break;
374 1.1 skrll case 1:
375 1.1 skrll insn &= bfd_get_16 (abfd, where);
376 1.1 skrll insn |= addend;
377 1.1 skrll bfd_put_16 (abfd, insn, where);
378 1.1 skrll break;
379 1.1 skrll case 2:
380 1.1 skrll insn &= bfd_get_32 (abfd, where);
381 1.1 skrll insn |= addend;
382 1.1 skrll bfd_put_32 (abfd, insn, where);
383 1.1 skrll break;
384 1.1 skrll default:
385 1.1 skrll abort ();
386 1.1 skrll }
387 1.1 skrll }
388 1.1 skrll
389 1.1 skrll /* Relocate a D10V ELF section. */
390 1.1 skrll
391 1.1 skrll static bfd_boolean
392 1.1 skrll elf32_d10v_relocate_section (bfd *output_bfd,
393 1.1 skrll struct bfd_link_info *info,
394 1.1 skrll bfd *input_bfd,
395 1.1 skrll asection *input_section,
396 1.1 skrll bfd_byte *contents,
397 1.1 skrll Elf_Internal_Rela *relocs,
398 1.1 skrll Elf_Internal_Sym *local_syms,
399 1.1 skrll asection **local_sections)
400 1.1 skrll {
401 1.1 skrll Elf_Internal_Shdr *symtab_hdr;
402 1.1 skrll struct elf_link_hash_entry **sym_hashes;
403 1.1 skrll Elf_Internal_Rela *rel, *relend;
404 1.1 skrll const char *name;
405 1.1 skrll
406 1.1 skrll symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
407 1.1 skrll sym_hashes = elf_sym_hashes (input_bfd);
408 1.1 skrll
409 1.1 skrll rel = relocs;
410 1.1 skrll relend = relocs + input_section->reloc_count;
411 1.1 skrll for (; rel < relend; rel++)
412 1.1 skrll {
413 1.1 skrll int r_type;
414 1.1 skrll reloc_howto_type *howto;
415 1.1 skrll unsigned long r_symndx;
416 1.1 skrll Elf_Internal_Sym *sym;
417 1.1 skrll asection *sec;
418 1.1 skrll struct elf_link_hash_entry *h;
419 1.1 skrll bfd_vma relocation;
420 1.1 skrll bfd_reloc_status_type r;
421 1.1 skrll
422 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info);
423 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info);
424 1.1 skrll
425 1.1 skrll if (r_type == R_D10V_GNU_VTENTRY
426 1.1 skrll || r_type == R_D10V_GNU_VTINHERIT)
427 1.1 skrll continue;
428 1.1 skrll
429 1.1 skrll howto = elf_d10v_howto_table + r_type;
430 1.1 skrll h = NULL;
431 1.1 skrll sym = NULL;
432 1.1 skrll sec = NULL;
433 1.1 skrll if (r_symndx < symtab_hdr->sh_info)
434 1.1 skrll {
435 1.1 skrll sym = local_syms + r_symndx;
436 1.1 skrll sec = local_sections[r_symndx];
437 1.1 skrll relocation = (sec->output_section->vma
438 1.1 skrll + sec->output_offset
439 1.1 skrll + sym->st_value);
440 1.1 skrll if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
441 1.1 skrll && ((sec->flags & SEC_MERGE) != 0
442 1.1.1.4 christos || (bfd_link_relocatable (info)
443 1.1 skrll && sec->output_offset != 0)))
444 1.1 skrll {
445 1.1 skrll bfd_vma addend;
446 1.1 skrll bfd_byte *where = contents + rel->r_offset;
447 1.1 skrll
448 1.1 skrll addend = extract_rel_addend (input_bfd, where, howto);
449 1.1 skrll
450 1.1.1.4 christos if (bfd_link_relocatable (info))
451 1.1 skrll addend += sec->output_offset;
452 1.1 skrll else
453 1.1 skrll {
454 1.1 skrll asection *msec = sec;
455 1.1 skrll addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
456 1.1 skrll addend);
457 1.1 skrll addend -= relocation;
458 1.1 skrll addend += msec->output_section->vma + msec->output_offset;
459 1.1 skrll }
460 1.1 skrll insert_rel_addend (input_bfd, where, howto, addend);
461 1.1 skrll }
462 1.1 skrll }
463 1.1 skrll else
464 1.1 skrll {
465 1.1.1.4 christos bfd_boolean unresolved_reloc, warned, ignored;
466 1.1 skrll
467 1.1 skrll RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
468 1.1 skrll r_symndx, symtab_hdr, sym_hashes,
469 1.1 skrll h, sec, relocation,
470 1.1.1.4 christos unresolved_reloc, warned, ignored);
471 1.1 skrll }
472 1.1 skrll
473 1.1.1.3 christos if (sec != NULL && discarded_section (sec))
474 1.1.1.2 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
475 1.1.1.3 christos rel, 1, relend, howto, 0, contents);
476 1.1 skrll
477 1.1.1.4 christos if (bfd_link_relocatable (info))
478 1.1 skrll continue;
479 1.1 skrll
480 1.1 skrll if (h != NULL)
481 1.1 skrll name = h->root.root.string;
482 1.1 skrll else
483 1.1 skrll {
484 1.1 skrll name = (bfd_elf_string_from_elf_section
485 1.1 skrll (input_bfd, symtab_hdr->sh_link, sym->st_name));
486 1.1 skrll if (name == NULL || *name == '\0')
487 1.1 skrll name = bfd_section_name (input_bfd, sec);
488 1.1 skrll }
489 1.1 skrll
490 1.1 skrll r = _bfd_final_link_relocate (howto, input_bfd, input_section,
491 1.1 skrll contents, rel->r_offset,
492 1.1 skrll relocation, (bfd_vma) 0);
493 1.1 skrll
494 1.1 skrll if (r != bfd_reloc_ok)
495 1.1 skrll {
496 1.1 skrll const char * msg = (const char *) 0;
497 1.1 skrll
498 1.1 skrll switch (r)
499 1.1 skrll {
500 1.1 skrll case bfd_reloc_overflow:
501 1.1 skrll if (!((*info->callbacks->reloc_overflow)
502 1.1 skrll (info, (h ? &h->root : NULL), name, howto->name,
503 1.1 skrll (bfd_vma) 0, input_bfd, input_section,
504 1.1 skrll rel->r_offset)))
505 1.1 skrll return FALSE;
506 1.1 skrll break;
507 1.1 skrll
508 1.1 skrll case bfd_reloc_undefined:
509 1.1 skrll if (!((*info->callbacks->undefined_symbol)
510 1.1 skrll (info, name, input_bfd, input_section,
511 1.1 skrll rel->r_offset, TRUE)))
512 1.1 skrll return FALSE;
513 1.1 skrll break;
514 1.1 skrll
515 1.1 skrll case bfd_reloc_outofrange:
516 1.1 skrll msg = _("internal error: out of range error");
517 1.1 skrll goto common_error;
518 1.1 skrll
519 1.1 skrll case bfd_reloc_notsupported:
520 1.1 skrll msg = _("internal error: unsupported relocation error");
521 1.1 skrll goto common_error;
522 1.1 skrll
523 1.1 skrll case bfd_reloc_dangerous:
524 1.1 skrll msg = _("internal error: dangerous error");
525 1.1 skrll goto common_error;
526 1.1 skrll
527 1.1 skrll default:
528 1.1 skrll msg = _("internal error: unknown error");
529 1.1 skrll /* fall through */
530 1.1 skrll
531 1.1 skrll common_error:
532 1.1 skrll if (!((*info->callbacks->warning)
533 1.1 skrll (info, msg, name, input_bfd, input_section,
534 1.1 skrll rel->r_offset)))
535 1.1 skrll return FALSE;
536 1.1 skrll break;
537 1.1 skrll }
538 1.1 skrll }
539 1.1 skrll }
540 1.1 skrll
541 1.1 skrll return TRUE;
542 1.1 skrll }
543 1.1 skrll #define ELF_ARCH bfd_arch_d10v
544 1.1 skrll #define ELF_MACHINE_CODE EM_D10V
545 1.1 skrll #define ELF_MACHINE_ALT1 EM_CYGNUS_D10V
546 1.1 skrll #define ELF_MAXPAGESIZE 0x1000
547 1.1 skrll
548 1.1.1.4 christos #define TARGET_BIG_SYM d10v_elf32_vec
549 1.1 skrll #define TARGET_BIG_NAME "elf32-d10v"
550 1.1 skrll
551 1.1 skrll #define elf_info_to_howto 0
552 1.1 skrll #define elf_info_to_howto_rel d10v_info_to_howto_rel
553 1.1 skrll #define elf_backend_object_p 0
554 1.1 skrll #define elf_backend_final_write_processing 0
555 1.1 skrll #define elf_backend_gc_mark_hook elf32_d10v_gc_mark_hook
556 1.1 skrll #define elf_backend_check_relocs elf32_d10v_check_relocs
557 1.1 skrll #define elf_backend_relocate_section elf32_d10v_relocate_section
558 1.1 skrll #define elf_backend_can_gc_sections 1
559 1.1 skrll
560 1.1 skrll #include "elf32-target.h"
561