1
1
/* D10V-specific support for 32-bit ELF
2
Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003
2
Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3
3
Free Software Foundation, Inc.
4
4
Contributed by Martin Hunt (hunt@cygnus.com).
38
38
static bfd_boolean elf32_d10v_check_relocs
39
39
PARAMS ((bfd *, struct bfd_link_info *, asection *,
40
40
const Elf_Internal_Rela *));
41
static bfd_vma extract_rel_addend
42
PARAMS ((bfd *, bfd_byte *, reloc_howto_type *));
43
static void insert_rel_addend
44
PARAMS ((bfd *, bfd_byte *, reloc_howto_type *, bfd_vma));
41
45
static bfd_boolean elf32_d10v_relocate_section
42
46
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
43
47
bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
330
334
/* This relocation describes the C++ object vtable hierarchy.
331
335
Reconstruct it for later use during GC. */
332
336
case R_D10V_GNU_VTINHERIT:
333
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
337
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
337
341
/* This relocation describes which C++ vtable entries are actually
338
342
used. Record for later use during GC. */
339
343
case R_D10V_GNU_VTENTRY:
340
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
344
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
354
extract_rel_addend (abfd, where, howto)
357
reloc_howto_type *howto;
364
insn = bfd_get_8 (abfd, where);
367
insn = bfd_get_16 (abfd, where);
370
insn = bfd_get_32 (abfd, where);
376
val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
377
/* We should really be testing for signed addends here, but we don't
378
have that info directly in the howto. */
379
if (howto->pc_relative)
382
sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
383
sign = sign >> howto->bitpos << howto->rightshift;
384
val = (val ^ sign) - sign;
390
insert_rel_addend (abfd, where, howto, addend)
393
reloc_howto_type *howto;
398
addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
399
insn = ~howto->dst_mask;
403
insn &= bfd_get_8 (abfd, where);
405
bfd_put_8 (abfd, insn, where);
408
insn &= bfd_get_16 (abfd, where);
410
bfd_put_16 (abfd, insn, where);
413
insn &= bfd_get_32 (abfd, where);
415
bfd_put_32 (abfd, insn, where);
349
422
/* Relocate a D10V ELF section. */
350
423
static bfd_boolean
351
424
elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
392
465
if (info->relocatable)
394
470
/* This is a relocatable link. We don't have to change
395
471
anything, unless the reloc is against a section symbol,
396
472
in which case we have to adjust according to where the
397
473
section symbol winds up in the output section. */
398
if (r_symndx < symtab_hdr->sh_info)
400
sym = local_syms + r_symndx;
401
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
403
sec = local_sections[r_symndx];
404
rel->r_addend += sec->output_offset + sym->st_value;
474
if (r_symndx >= symtab_hdr->sh_info)
477
sym = local_syms + r_symndx;
478
if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
481
sec = local_sections[r_symndx];
482
val = sec->output_offset;
486
where = contents + rel->r_offset;
487
val += extract_rel_addend (input_bfd, where, howto);
488
insert_rel_addend (input_bfd, where, howto, val);
417
498
sym = local_syms + r_symndx;
418
499
sec = local_sections[r_symndx];
419
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
500
relocation = (sec->output_section->vma
503
if ((sec->flags & SEC_MERGE)
504
&& ELF_ST_TYPE (sym->st_info) == STT_SECTION)
508
bfd_byte *where = contents + rel->r_offset;
510
addend = extract_rel_addend (input_bfd, where, howto);
512
addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
513
addend -= relocation;
514
addend += msec->output_section->vma + msec->output_offset;
515
insert_rel_addend (input_bfd, where, howto, addend);
423
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
424
while (h->root.type == bfd_link_hash_indirect
425
|| h->root.type == bfd_link_hash_warning)
426
h = (struct elf_link_hash_entry *) h->root.u.i.link;
427
if (h->root.type == bfd_link_hash_defined
428
|| h->root.type == bfd_link_hash_defweak)
430
sec = h->root.u.def.section;
431
relocation = (h->root.u.def.value
432
+ sec->output_section->vma
433
+ sec->output_offset);
435
else if (h->root.type == bfd_link_hash_undefweak)
439
if (!((*info->callbacks->undefined_symbol)
440
(info, h->root.root.string, input_bfd,
441
input_section, rel->r_offset, TRUE)))
520
bfd_boolean unresolved_reloc, warned;
522
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
523
r_symndx, symtab_hdr, sym_hashes,
525
unresolved_reloc, warned);
457
538
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
458
539
contents, rel->r_offset,
459
relocation, rel->r_addend);
540
relocation, (bfd_vma) 0);
461
542
if (r != bfd_reloc_ok)