diff options
author | Alan Modra <amodra@gmail.com> | 2003-06-10 07:44:11 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2003-06-10 07:44:11 +0000 |
commit | adadcc0cc96a9373f7dfb9b7ca3c57d630872730 (patch) | |
tree | 00f2f222425404d217e030d6347b5a652b41b802 /bfd/elf64-ppc.c | |
parent | 2a93846b50ab8ecbbcc7775de29f3494889cb3f9 (diff) | |
download | gdb-adadcc0cc96a9373f7dfb9b7ca3c57d630872730.zip gdb-adadcc0cc96a9373f7dfb9b7ca3c57d630872730.tar.gz gdb-adadcc0cc96a9373f7dfb9b7ca3c57d630872730.tar.bz2 |
Add "attn", "lq" and "stq" power4 insns.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r-- | bfd/elf64-ppc.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 0e7576f..bc47809 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -7315,7 +7315,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, bfd_vma relocation; bfd_boolean unresolved_reloc; bfd_boolean warned; - long insn; + long insn, mask; struct ppc_stub_hash_entry *stub_entry; bfd_vma max_br_offset; bfd_vma from; @@ -8406,12 +8406,23 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, case R_PPC64_TPREL16_LO_DS: case R_PPC64_DTPREL16_DS: case R_PPC64_DTPREL16_LO_DS: - if (((relocation + addend) & 3) != 0) + insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3)); + mask = 3; + /* If this reloc is against an lq insn, then the value must be + a multiple of 16. This is somewhat of a hack, but the + "correct" way to do this by defining _DQ forms of all the + _DS relocs bloats all reloc switches in this file. It + doesn't seem to make much sense to use any of these relocs + in data, so testing the insn should be safe. */ + if ((insn & (0x3f << 26)) == (56 << 26)) + mask = 15; + if (((relocation + addend) & mask) != 0) { (*_bfd_error_handler) - (_("%s: error: relocation %s not a multiple of 4"), + (_("%s: error: relocation %s not a multiple of %d"), bfd_archive_filename (input_bfd), - ppc64_elf_howto_table[(int) r_type]->name); + ppc64_elf_howto_table[(int) r_type]->name, + mask + 1); bfd_set_error (bfd_error_bad_value); ret = FALSE; continue; |