From 54613d67ea96b0129b141bdeb3016f72e223f6af Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Wed, 12 Sep 2012 16:25:37 +0000 Subject: 2012-09-11 Chris Schlumberger-Socha 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 #::. (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. --- gas/config/tc-aarch64.c | 123 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 37 deletions(-) (limited to 'gas/config') 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; + /* #:: */ + 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; + } + + /* #:: */ + 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)) + /* #:: */ + /* 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; -- cgit v1.2.1