summaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorRichard Earnshaw <richard.earnshaw@arm.com>2012-09-12 16:25:37 +0000
committerRichard Earnshaw <richard.earnshaw@arm.com>2012-09-12 16:25:37 +0000
commit54613d67ea96b0129b141bdeb3016f72e223f6af (patch)
tree402085afd1b9be9857372049d24be84fa86acc40 /gas/config
parente84e0bcdb9d526c1bec724e3a77c03e6d704e04f (diff)
downloadbinutils-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.c123
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;