diff options
author | Richard Earnshaw <richard.earnshaw@arm.com> | 2012-09-12 16:25:37 +0000 |
---|---|---|
committer | Richard Earnshaw <richard.earnshaw@arm.com> | 2012-09-12 16:25:37 +0000 |
commit | 54613d67ea96b0129b141bdeb3016f72e223f6af (patch) | |
tree | 402085afd1b9be9857372049d24be84fa86acc40 /gas/config | |
parent | e84e0bcdb9d526c1bec724e3a77c03e6d704e04f (diff) | |
download | binutils-redhat-54613d67ea96b0129b141bdeb3016f72e223f6af.tar.gz |
2012-09-11 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
bfd/
* bfd-in2.h: Regenerated.
* elf64-aarch64.c
(elf64_aarch64_howto_table): Add R_AARCH64_GOT_LD_PREL19 reloc to HOWTO.
(elf64_aarch64_reloc_map): Add reloc entry.
(aarch64_resolve_relocation): Likewise.
(bfd_elf_aarch64_put_addend): Likewise.
(aarch64_reloc_got_type): Likewise.
(elf64_aarch64_final_link_relocate): Likewise.
(lf64_aarch64_check_relocs): Likewise.
(elf64_aarch64_check_relocs): New case for R_AARCH64_ADR_PREL_LO21
reloc.
* libbfd.h: Regenerated.
* reloc.c (R_AARCH64_GOT_LD_PREL19): New reloc.
gas/
* config/tc-aarch64.c
(reloc_table): Add reloc to table entry.
(parse_address_main): Add support for #:<reloc_op>:<symbol>.
(parse_operands): Check for unused reloc.
(md_apply_fix): New case for reloc.
(aarch64_force_relocation): Likewise.
gas/testsuite
* gas/aarch64/reloc-insn.d
(BFD_RELOC_AARCH64_GOT_LD_PREL19): Add expected asm for new reloc test.
* gas/aarch64/reloc-insn.s
(BFD_RELOC_AARCH64_GOT_LD_PREL19): Add test for reloc.
include/
* elf/aarch64.h (R_AARCH64_GOT_LD_PREL19): New reloc.
ld/testsuite
* ld-aarch64/aarch64-elf.exp: New reloc tests.
* ld-aarch64/emit-relocs-309-low-bad.d: New file. Expected asm for test
failure (lower bound overflow).
* ld-aarch64/emit-relocs-309-low.d: New file. Expected asm for test
success (lower bound).
* ld-aarch64/emit-relocs-309-up-bad.d: New file. Expected asm for test
failure (upper bound overflow).
* ld-aarch64/emit-relocs-309-up.d: New file. Expected asm for test
success (upper bound).
* ld-aarch64/emit-relocs-309.s: New file. Asm for new reloc tests.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-aarch64.c | 123 |
1 files changed, 86 insertions, 37 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 4333e8ef23..e695e88462 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2298,6 +2298,12 @@ static struct reloc_table_entry reloc_table[] = { BFD_RELOC_AARCH64_MOVW_G3, 0, 0}, + /* Get to the GOT entry for a symbol. */ + {"got_prel19", 0, + 0, + 0, + 0, + BFD_RELOC_AARCH64_GOT_LD_PREL19}, /* Get to the page containing GOT entry for a symbol. */ {"got", 1, BFD_RELOC_AARCH64_ADR_GOT_PAGE, @@ -2816,14 +2822,53 @@ parse_address_main (char **str, aarch64_opnd_info *operand, int reloc, operand->addr.pcrel = 1; operand->addr.preind = 1; - if (skip_past_char (&p, '=')) - /* =immediate; need to generate the literal in the liternal pool. */ - inst.gen_lit_pool = 1; + /* #:<reloc_op>:<symbol> */ + skip_past_char (&p, '#'); + if (reloc && skip_past_char (&p, ':')) + { + struct reloc_table_entry *entry; + + /* Try to parse a relocation modifier. Anything else is + an error. */ + entry = find_reloc_table_entry (&p); + if (! entry) + { + set_syntax_error (_("unknown relocation modifier")); + return FALSE; + } + + if (entry->ldst_type == 0) + { + set_syntax_error + (_("this relocation modifier is not allowed on this " + "instruction")); + return FALSE; + } + + /* #:<reloc_op>: */ + if (! my_get_expression (exp, &p, GE_NO_PREFIX, 1)) + { + set_syntax_error (_("invalid relocation expression")); + return FALSE; + } - if (! my_get_expression (exp, &p, GE_NO_PREFIX, 1)) + /* #:<reloc_op>:<expr> */ + /* Record the load/store relocation type. */ + inst.reloc.type = entry->ldst_type; + inst.reloc.pc_rel = entry->pc_rel; + } + else { - set_syntax_error (_("invalid address")); - return FALSE; + + if (skip_past_char (&p, '=')) + /* =immediate; need to generate the literal in the literal pool. */ + inst.gen_lit_pool = 1; + + if (!my_get_expression (exp, &p, GE_NO_PREFIX, 1)) + { + set_syntax_error (_("invalid address")); + return FALSE; + } } *str = p; @@ -4889,37 +4934,39 @@ parse_operands (char *str, const aarch64_opcode *opcode) else { info->imm.value = 0; - switch (opcode->iclass) - { - case compbranch: - case condbranch: - /* e.g. CBZ or B.COND */ - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19); - inst.reloc.type = BFD_RELOC_AARCH64_BRANCH19; - break; - case testbranch: - /* e.g. TBZ */ - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL14); - inst.reloc.type = BFD_RELOC_AARCH64_TSTBR14; - break; - case branch_imm: - /* e.g. B or BL */ - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL26); - inst.reloc.type = (opcode->op == OP_BL) - ? BFD_RELOC_AARCH64_CALL26 : BFD_RELOC_AARCH64_JUMP26; - break; - case loadlit: - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19); - inst.reloc.type = BFD_RELOC_AARCH64_LD_LO19_PCREL; - break; - case pcreladdr: - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL21); - inst.reloc.type = BFD_RELOC_AARCH64_ADR_LO21_PCREL; - break; - default: - gas_assert (0); - abort (); - } + if (inst.reloc.type == BFD_RELOC_UNUSED) + switch (opcode->iclass) + { + case compbranch: + case condbranch: + /* e.g. CBZ or B.COND */ + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19); + inst.reloc.type = BFD_RELOC_AARCH64_BRANCH19; + break; + case testbranch: + /* e.g. TBZ */ + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL14); + inst.reloc.type = BFD_RELOC_AARCH64_TSTBR14; + break; + case branch_imm: + /* e.g. B or BL */ + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL26); + inst.reloc.type = + (opcode->op == OP_BL) ? BFD_RELOC_AARCH64_CALL26 + : BFD_RELOC_AARCH64_JUMP26; + break; + case loadlit: + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19); + inst.reloc.type = BFD_RELOC_AARCH64_LD_LO19_PCREL; + break; + case pcreladdr: + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL21); + inst.reloc.type = BFD_RELOC_AARCH64_ADR_LO21_PCREL; + break; + default: + gas_assert (0); + abort (); + } inst.reloc.pc_rel = 1; } break; @@ -6418,6 +6465,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) case BFD_RELOC_AARCH64_LDST32_LO12: case BFD_RELOC_AARCH64_LDST64_LO12: case BFD_RELOC_AARCH64_LDST128_LO12: + case BFD_RELOC_AARCH64_GOT_LD_PREL19: case BFD_RELOC_AARCH64_ADR_GOT_PAGE: case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: /* Should always be exported to object file, see @@ -6575,6 +6623,7 @@ aarch64_force_relocation (struct fix *fixp) case BFD_RELOC_AARCH64_LDST32_LO12: case BFD_RELOC_AARCH64_LDST64_LO12: case BFD_RELOC_AARCH64_LDST128_LO12: + case BFD_RELOC_AARCH64_GOT_LD_PREL19: /* Always leave these relocations for the linker. */ return 1; |