aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2021-04-06 13:27:50 +0100
committerNick Clifton <nickc@redhat.com>2021-04-06 13:27:50 +0100
commiteac4eb8ecb2626ef7711d8f6bee9e870ae435604 (patch)
treefd02dab5fb608d6b4383540e03f36dcd295f9dd8 /gas
parentda0835aebea71232f6b4fb4dea3ee18bdef0c139 (diff)
downloadgdb-eac4eb8ecb2626ef7711d8f6bee9e870ae435604.zip
gdb-eac4eb8ecb2626ef7711d8f6bee9e870ae435604.tar.gz
gdb-eac4eb8ecb2626ef7711d8f6bee9e870ae435604.tar.bz2
Fix a problem assembling AArch64 sources when a relocation is generated against a symbol that has a defined value.
PR 27217 * config/tc-aarch64.c (my_get_expression): Rename to aarch64_get_expression. Add a fifth argument to enable deferring of expression resolution. (parse_typed_reg): Update calls to my_get_expression. (parse_vector_reg_list): Likewise. (parse_immediate_expression): Likewise. (parse_big_immediate): Likewise. (parse_shift): Likewise. (parse_shifter_operand_imm): Likewise. (parse_operands): Likewise. (parse_shifter_operand_reloc): Update calls to my_get_expression and call aarch64_force_reloc to determine the value of the new fifth argument. (parse_address_main): Likewise. (parse_half): Likewise. (parse_adrp): Likewise. (aarch64_force_reloc): New function. Contains code extracted from... (aarch64_force_relocation): ... here. * testsuite/gas/aarch64/pr27217.s: New test case. * testsuite/gas/aarch64/pr27217.d: New test driver.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog24
-rw-r--r--gas/config/tc-aarch64.c320
-rw-r--r--gas/testsuite/gas/aarch64/pr27217.d15
-rw-r--r--gas/testsuite/gas/aarch64/pr27217.s16
4 files changed, 235 insertions, 140 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8558a87..f62e817 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,27 @@
+2021-04-06 Nick Clifton <nickc@redhat.com>
+
+ PR 27217
+ * config/tc-aarch64.c (my_get_expression): Rename to
+ aarch64_get_expression. Add a fifth argument to enable deferring
+ of expression resolution.
+ (parse_typed_reg): Update calls to my_get_expression.
+ (parse_vector_reg_list): Likewise.
+ (parse_immediate_expression): Likewise.
+ (parse_big_immediate): Likewise.
+ (parse_shift): Likewise.
+ (parse_shifter_operand_imm): Likewise.
+ (parse_operands): Likewise.
+ (parse_shifter_operand_reloc): Update calls to my_get_expression
+ and call aarch64_force_reloc to determine the value of the new
+ fifth argument.
+ (parse_address_main): Likewise.
+ (parse_half): Likewise.
+ (parse_adrp): Likewise.
+ (aarch64_force_reloc): New function. Contains code extracted from...
+ (aarch64_force_relocation): ... here.
+ * testsuite/gas/aarch64/pr27217.s: New test case.
+ * testsuite/gas/aarch64/pr27217.d: New test driver.
+
2021-04-06 Jan Beulich <jbeulich@suse.com>
* write.c (fixup_segment): Move add_symbol_segment declaration
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 1870955..f67ee1e 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -548,53 +548,66 @@ skip_past_char (char **str, char c)
/* Arithmetic expressions (possibly involving symbols). */
-static bool in_my_get_expression_p = false;
+static bool in_aarch64_get_expression = false;
-/* Third argument to my_get_expression. */
-#define GE_NO_PREFIX 0
-#define GE_OPT_PREFIX 1
+/* Third argument to aarch64_get_expression. */
+#define GE_NO_PREFIX false
+#define GE_OPT_PREFIX true
+
+/* Fourth argument to aarch64_get_expression. */
+#define ALLOW_ABSENT false
+#define REJECT_ABSENT true
+
+/* Fifth argument to aarch64_get_expression. */
+#define NORMAL_RESOLUTION false
/* Return TRUE if the string pointed by *STR is successfully parsed
as an valid expression; *EP will be filled with the information of
- such an expression. Otherwise return FALSE. */
+ such an expression. Otherwise return FALSE.
+
+ If ALLOW_IMMEDIATE_PREFIX is true then skip a '#' at the start.
+ If REJECT_ABSENT is true then trat missing expressions as an error.
+ If DEFER_RESOLUTION is true, then do not resolve expressions against
+ constant symbols. Necessary if the expression is part of a fixup
+ that uses a reloc that must be emitted. */
static bool
-my_get_expression (expressionS * ep, char **str, int prefix_mode,
- int reject_absent)
+aarch64_get_expression (expressionS * ep,
+ char ** str,
+ bool allow_immediate_prefix,
+ bool reject_absent,
+ bool defer_resolution)
{
char *save_in;
segT seg;
- int prefix_present_p = 0;
+ bool prefix_present = false;
- switch (prefix_mode)
+ if (allow_immediate_prefix)
{
- case GE_NO_PREFIX:
- break;
- case GE_OPT_PREFIX:
if (is_immediate_prefix (**str))
{
(*str)++;
- prefix_present_p = 1;
+ prefix_present = true;
}
- break;
- default:
- abort ();
}
memset (ep, 0, sizeof (expressionS));
save_in = input_line_pointer;
input_line_pointer = *str;
- in_my_get_expression_p = true;
- seg = expression (ep);
- in_my_get_expression_p = false;
+ in_aarch64_get_expression = true;
+ if (defer_resolution)
+ seg = deferred_expression (ep);
+ else
+ seg = expression (ep);
+ in_aarch64_get_expression = false;
if (ep->X_op == O_illegal || (reject_absent && ep->X_op == O_absent))
{
/* We found a bad expression in md_operand(). */
*str = input_line_pointer;
input_line_pointer = save_in;
- if (prefix_present_p && ! error_p ())
+ if (prefix_present && ! error_p ())
set_fatal_syntax_error (_("bad expression"));
else
set_first_syntax_error (_("bad expression"));
@@ -605,7 +618,8 @@ my_get_expression (expressionS * ep, char **str, int prefix_mode,
if (seg != absolute_section
&& seg != text_section
&& seg != data_section
- && seg != bss_section && seg != undefined_section)
+ && seg != bss_section
+ && seg != undefined_section)
{
set_syntax_error (_("bad segment"));
*str = input_line_pointer;
@@ -685,7 +699,7 @@ md_atof (int type, char *litP, int *sizeP)
void
md_operand (expressionS * exp)
{
- if (in_my_get_expression_p)
+ if (in_aarch64_get_expression)
exp->X_op = O_illegal;
}
@@ -1062,7 +1076,8 @@ parse_typed_reg (char **ccp, aarch64_reg_type type, aarch64_reg_type *rtype,
atype.defined |= NTA_HASINDEX;
- my_get_expression (&exp, &str, GE_NO_PREFIX, 1);
+ aarch64_get_expression (&exp, &str, GE_NO_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION);
if (exp.X_op != O_constant)
{
@@ -1265,7 +1280,8 @@ parse_vector_reg_list (char **ccp, aarch64_reg_type type,
{
expressionS exp;
- my_get_expression (&exp, &str, GE_NO_PREFIX, 1);
+ aarch64_get_expression (&exp, &str, GE_NO_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION);
if (exp.X_op != O_constant)
{
set_first_syntax_error (_("constant expression required."));
@@ -2208,7 +2224,8 @@ parse_immediate_expression (char **str, expressionS *exp,
return false;
}
- my_get_expression (exp, str, GE_OPT_PREFIX, 1);
+ aarch64_get_expression (exp, str, GE_OPT_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION);
if (exp->X_op == O_absent)
{
@@ -2442,7 +2459,8 @@ parse_big_immediate (char **str, int64_t *imm, aarch64_reg_type reg_type)
return false;
}
- my_get_expression (&inst.reloc.exp, &ptr, GE_OPT_PREFIX, 1);
+ aarch64_get_expression (&inst.reloc.exp, &ptr, GE_OPT_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION);
if (inst.reloc.exp.X_op == O_constant)
*imm = inst.reloc.exp.X_add_number;
@@ -2526,7 +2544,8 @@ struct reloc_table_entry
bfd_reloc_code_real_type ld_literal_type;
};
-static struct reloc_table_entry reloc_table[] = {
+static struct reloc_table_entry reloc_table[] =
+{
/* Low 12 bits of absolute address: ADD/i and LDR/STR */
{"lo12", 0,
0, /* adr_type */
@@ -3079,6 +3098,114 @@ find_reloc_table_entry (char **str)
return NULL;
}
+/* Returns 0 if the relocation should never be forced,
+ 1 if the relocation must be forced, and -1 if either
+ result is OK. */
+
+static signed int
+aarch64_force_reloc (unsigned int type)
+{
+ switch (type)
+ {
+ case BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP:
+ /* Perform these "immediate" internal relocations
+ even if the symbol is extern or weak. */
+ return 0;
+
+ case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC:
+ /* Pseudo relocs that need to be fixed up according to
+ ilp32_p. */
+ return 0;
+
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
+ case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
+ case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LDST128_LO12:
+ case BFD_RELOC_AARCH64_LDST16_LO12:
+ case BFD_RELOC_AARCH64_LDST32_LO12:
+ case BFD_RELOC_AARCH64_LDST64_LO12:
+ case BFD_RELOC_AARCH64_LDST8_LO12:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
+ case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
+ case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
+ case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
+ case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+ case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
+ case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2:
+ case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ /* Always leave these relocations for the linker. */
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+int
+aarch64_force_relocation (struct fix *fixp)
+{
+ int res = aarch64_force_reloc (fixp->fx_r_type);
+
+ if (res == -1)
+ return generic_force_reloc (fixp);
+ return res;
+}
+
/* Mode argument to parse_shift and parser_shifter_operand. */
enum parse_shift_mode
{
@@ -3225,7 +3352,8 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode)
p++;
exp_has_prefix = 1;
}
- my_get_expression (&exp, &p, GE_NO_PREFIX, 0);
+ (void) aarch64_get_expression (&exp, &p, GE_NO_PREFIX, ALLOW_ABSENT,
+ NORMAL_RESOLUTION);
}
if (kind == AARCH64_MOD_MUL_VL)
/* For consistency, give MUL VL the same shift amount as an implicit
@@ -3288,7 +3416,8 @@ parse_shifter_operand_imm (char **str, aarch64_opnd_info *operand,
p = *str;
/* Accept an immediate expression. */
- if (! my_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX, 1))
+ if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX,
+ REJECT_ABSENT, NORMAL_RESOLUTION))
return false;
/* Accept optional LSL for arithmetic immediate values. */
@@ -3411,9 +3540,11 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
p = *str;
/* Next, we parse the expression. */
- if (! my_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX, 1))
+ if (! aarch64_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX,
+ REJECT_ABSENT,
+ aarch64_force_reloc (entry->add_type) == 1))
return false;
-
+
/* Record the relocation type (use the ADD variant here). */
inst.reloc.type = entry->add_type;
inst.reloc.pc_rel = entry->pc_rel;
@@ -3557,12 +3688,12 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
}
/* #:<reloc_op>: */
- if (! my_get_expression (exp, &p, GE_NO_PREFIX, 1))
+ if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+ aarch64_force_reloc (entry->add_type) == 1))
{
set_syntax_error (_("invalid relocation expression"));
return false;
}
-
/* #:<reloc_op>:<expr> */
/* Record the relocation type. */
inst.reloc.type = ty;
@@ -3570,12 +3701,12 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
}
else
{
-
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))
+ if (!aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION))
{
set_syntax_error (_("invalid address"));
return false;
@@ -3681,7 +3812,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
/* We now have the group relocation table entry corresponding to
the name in the assembler source. Next, we parse the
expression. */
- if (! my_get_expression (exp, &p, GE_NO_PREFIX, 1))
+ if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+ aarch64_force_reloc (entry->add_type) == 1))
{
set_syntax_error (_("invalid relocation expression"));
return false;
@@ -3694,7 +3826,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
}
else
{
- if (! my_get_expression (exp, &p, GE_OPT_PREFIX, 1))
+ if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION))
{
set_syntax_error (_("invalid expression in the address"));
return false;
@@ -3750,7 +3883,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
operand->addr.offset.regno = reg->number;
operand->addr.offset.is_reg = 1;
}
- else if (! my_get_expression (exp, &p, GE_OPT_PREFIX, 1))
+ else if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION))
{
/* [Xn],#expr */
set_syntax_error (_("invalid expression in the address"));
@@ -3843,6 +3977,7 @@ parse_half (char **str, int *internal_fixup_p)
/* Try to parse a relocation. Anything else is an error. */
++p;
+
if (!(entry = find_reloc_table_entry (&p)))
{
set_syntax_error (_("unknown relocation modifier"));
@@ -3861,7 +3996,8 @@ parse_half (char **str, int *internal_fixup_p)
else
*internal_fixup_p = 1;
- if (! my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, 1))
+ if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+ aarch64_force_reloc (inst.reloc.type) == 1))
return false;
*str = p;
@@ -3903,10 +4039,9 @@ parse_adrp (char **str)
inst.reloc.type = BFD_RELOC_AARCH64_ADR_HI21_PCREL;
inst.reloc.pc_rel = 1;
-
- if (! my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, 1))
+ if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+ aarch64_force_reloc (inst.reloc.type) == 1))
return false;
-
*str = p;
return true;
}
@@ -6023,8 +6158,9 @@ parse_operands (char *str, const aarch64_opcode *opcode)
reg_name_p (str, REG_TYPE_VN))
goto failure;
str = saved;
- po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
- GE_OPT_PREFIX, 1));
+ po_misc_or_fail (aarch64_get_expression (&inst.reloc.exp, &str,
+ GE_OPT_PREFIX, REJECT_ABSENT,
+ NORMAL_RESOLUTION));
/* The MOV immediate alias will be fixed up by fix_mov_imm_insn
later. fix_mov_imm_insn will try to determine a machine
instruction (MOVZ, MOVN or ORR) for it and will issue an error
@@ -8436,102 +8572,6 @@ cons_fix_new_aarch64 (fragS * frag, int where, int size, expressionS * exp)
fix_new_exp (frag, where, (int) size, exp, pcrel, type);
}
-int
-aarch64_force_relocation (struct fix *fixp)
-{
- switch (fixp->fx_r_type)
- {
- case BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP:
- /* Perform these "immediate" internal relocations
- even if the symbol is extern or weak. */
- return 0;
-
- case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
- case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
- case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC:
- /* Pseudo relocs that need to be fixed up according to
- ilp32_p. */
- return 0;
-
- case BFD_RELOC_AARCH64_ADD_LO12:
- case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
- case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
- case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
- case BFD_RELOC_AARCH64_GOT_LD_PREL19:
- case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
- case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
- case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
- case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
- case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
- case BFD_RELOC_AARCH64_LDST128_LO12:
- case BFD_RELOC_AARCH64_LDST16_LO12:
- case BFD_RELOC_AARCH64_LDST32_LO12:
- case BFD_RELOC_AARCH64_LDST64_LO12:
- case BFD_RELOC_AARCH64_LDST8_LO12:
- case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
- case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
- case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
- case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
- case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
- case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
- case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
- case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
- case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
- case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
- case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
- case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
- case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
- case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
- case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
- case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
- case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
- case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12:
- case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
- case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
- case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0:
- case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
- case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1:
- case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC:
- case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2:
- case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
- case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
- case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
- case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
- case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
- case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
- case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
- case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
- /* Always leave these relocations for the linker. */
- return 1;
-
- default:
- break;
- }
-
- return generic_force_reloc (fixp);
-}
-
#ifdef OBJ_ELF
/* Implement md_after_parse_args. This is the earliest time we need to decide
diff --git a/gas/testsuite/gas/aarch64/pr27217.d b/gas/testsuite/gas/aarch64/pr27217.d
new file mode 100644
index 0000000..4645ff5
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pr27217.d
@@ -0,0 +1,15 @@
+# Check that expressions that generate relocations work when the symbol is a constant.
+#name: PR27212
+#objdump: -rd
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0+000 <.*>:
+[ ]+0:[ ]+90000000[ ]+adrp[ ]+x0, 12345678[ ]+<bar>
+[ ]+0:[ ]+R_AARCH64_ADR_PREL_PG_HI21[ ]+bar
+[ ]+4:[ ]+91000000[ ]+add[ ]+x0, x0, #0x0
+[ ]+4:[ ]+R_AARCH64_ADD_ABS_LO12_NC[ ]+bar
+[ ]+8:[ ]+d65f03c0[ ]+ret
+#pass
diff --git a/gas/testsuite/gas/aarch64/pr27217.s b/gas/testsuite/gas/aarch64/pr27217.s
new file mode 100644
index 0000000..8cb9230
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pr27217.s
@@ -0,0 +1,16 @@
+ .arch armv8-a
+ .file "set.c"
+ .text
+ // Start of user assembly
+ .set bar, 0x12345678
+ // End of user assembly
+ .align 2
+ .p2align 4,,11
+ .global foo
+ .type foo, %function
+foo:
+ adrp x0, bar
+ add x0, x0, :lo12:bar
+ ret
+ .size foo, .-foo
+ .ident "GCC: (GNU) 10.2.1 20201030 (RTEMS 6, RSB "