]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
aarch64: re-work PR gas/27217 fix again
authorJan Beulich <jbeulich@suse.com>
Fri, 10 Jan 2025 07:42:41 +0000 (08:42 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 10 Jan 2025 07:42:41 +0000 (08:42 +0100)
Commit c1723a8118f0 ("Arm64: re-work PR gas/27217 fix") really was only
a band-aid; Nick's original solution to the problem was technically
preferable, yet didn't work when . came into play. Undo most of that
change, now that expr_defer expression parsing mode latches dot as is
desired here.

Also add testing for the . case, which I should have done already back
at the time.

gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/pr27217.d
gas/testsuite/gas/aarch64/pr27217.s

index 3046d3d8b5e216bf621a96d5f23fdb0cb1562a8d..47d9e93fd166a38fc2c4c2f7b7c3dd0fd8bfedb5 100644 (file)
@@ -662,18 +662,25 @@ static bool in_aarch64_get_expression = false;
 #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.
 
    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 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
 aarch64_get_expression (expressionS *  ep,
                        char **        str,
                        bool           allow_immediate_prefix,
-                       bool           reject_absent)
+                       bool           reject_absent,
+                       bool           defer_resolution)
 {
   char *save_in;
   segT seg;
@@ -693,7 +700,10 @@ aarch64_get_expression (expressionS *  ep,
   save_in = input_line_pointer;
   input_line_pointer = *str;
   in_aarch64_get_expression = true;
-  seg = expression (ep);
+  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))
@@ -1159,7 +1169,8 @@ parse_index_expression (char **str, int64_t *imm)
 {
   expressionS exp;
 
-  aarch64_get_expression (&exp, str, GE_NO_PREFIX, REJECT_ABSENT);
+  aarch64_get_expression (&exp, str, GE_NO_PREFIX, REJECT_ABSENT,
+                         NORMAL_RESOLUTION);
   if (exp.X_op != O_constant)
     {
       first_error (_("constant expression required"));
@@ -2542,7 +2553,8 @@ parse_immediate_expression (char **str, expressionS *exp,
       return false;
     }
 
-  aarch64_get_expression (exp, str, GE_OPT_PREFIX, REJECT_ABSENT);
+  aarch64_get_expression (exp, str, GE_OPT_PREFIX, REJECT_ABSENT,
+                         NORMAL_RESOLUTION);
 
   if (exp->X_op == O_absent)
     {
@@ -2776,7 +2788,8 @@ parse_big_immediate (char **str, int64_t *imm, aarch64_reg_type reg_type)
       return false;
     }
 
-  aarch64_get_expression (&inst.reloc.exp, &ptr, GE_OPT_PREFIX, REJECT_ABSENT);
+  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;
@@ -3673,7 +3686,8 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode)
          p++;
          exp_has_prefix = 1;
        }
-      aarch64_get_expression (&exp, &p, GE_NO_PREFIX, ALLOW_ABSENT);
+      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
@@ -3737,7 +3751,7 @@ parse_shifter_operand_imm (char **str, aarch64_opnd_info *operand,
 
   /* Accept an immediate expression.  */
   if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX,
-                               REJECT_ABSENT))
+                               REJECT_ABSENT, NORMAL_RESOLUTION))
     return false;
 
   /* Accept optional LSL for arithmetic immediate values.  */
@@ -3896,7 +3910,8 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
 
       /* Next, we parse the expression.  */
       if (! aarch64_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX,
-                                   REJECT_ABSENT))
+                                   REJECT_ABSENT,
+                                   aarch64_force_reloc (entry->add_type) == 1))
        return false;
 
       /* Record the relocation type (use the ADD variant here).  */
@@ -4091,7 +4106,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
            }
 
          /* #:<reloc_op>:  */
-         if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT))
+         if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+                                       aarch64_force_reloc (ty) == 1))
            {
              set_syntax_error (_("invalid relocation expression"));
              return false;
@@ -4107,7 +4123,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
            /* =immediate; need to generate the literal in the literal pool. */
            inst.gen_lit_pool = 1;
 
-         if (!aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT))
+         if (!aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+                                      NORMAL_RESOLUTION))
            {
              set_syntax_error (_("invalid address"));
              return false;
@@ -4221,7 +4238,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 (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT))
+             if (! aarch64_get_expression (exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+                                           aarch64_force_reloc (entry->ldst_type) == 1))
                {
                  set_syntax_error (_("invalid relocation expression"));
                  return false;
@@ -4234,7 +4252,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
            }
          else
            {
-             if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT))
+             if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT,
+                                           NORMAL_RESOLUTION))
                {
                  set_syntax_error (_("invalid expression in the address"));
                  return false;
@@ -4290,7 +4309,8 @@ parse_address_main (char **str, aarch64_opnd_info *operand,
          operand->addr.offset.regno = reg->number;
          operand->addr.offset.is_reg = 1;
        }
-      else if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT))
+      else if (! aarch64_get_expression (exp, &p, GE_OPT_PREFIX, REJECT_ABSENT,
+                                        NORMAL_RESOLUTION))
        {
          /* [Xn],#expr */
          set_syntax_error (_("invalid expression in the address"));
@@ -4418,7 +4438,8 @@ parse_half (char **str, int *internal_fixup_p)
   else
     *internal_fixup_p = 1;
 
-  if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT))
+  if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
+                               aarch64_force_reloc (inst.reloc.type) == 1))
     return false;
 
   *str = p;
@@ -4460,7 +4481,8 @@ parse_adrp (char **str)
     inst.reloc.type = BFD_RELOC_AARCH64_ADR_HI21_PCREL;
 
   inst.reloc.pc_rel = 1;
-  if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT))
+  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;
@@ -7222,7 +7244,8 @@ parse_operands (char *str, const aarch64_opcode *opcode)
              goto failure;
            str = saved;
            po_misc_or_fail (aarch64_get_expression (&inst.reloc.exp, &str,
-                                                    GE_OPT_PREFIX, REJECT_ABSENT));
+                                                    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
@@ -9604,8 +9627,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
 
   /* Note whether this will delete the relocation.  */
 
-  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel
-      && aarch64_force_reloc (fixP->fx_r_type) <= 0)
+  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
     fixP->fx_done = 1;
 
   /* Process the relocations.  */
index ddbfb3229d30b75605ddc7368a24ed89cdf4179b..8dc355b3f286d72cd80329bedc878a8a6fd7fdd5 100644 (file)
@@ -10,8 +10,19 @@ Disassembly of section \.text:
 
 0+000 <.*>:
 [      ]+0:[   ]+90000000[     ]+adrp[         ]+x0, [0-9]*[   ]+<.*>
-[      ]+0:[   ]+R_AARCH64(|_P32)_ADR_PREL_PG_HI21[    ]+\*ABS\*\+0x12345678
+[      ]+0:[   ]+R_AARCH64(|_P32)_ADR_PREL_PG_HI21[    ]+bar
 [      ]+4:[   ]+91000000[     ]+add[  ]+x0, x0, #0x0
-[      ]+4:[   ]+R_AARCH64(|_P32)_ADD_ABS_LO12_NC[     ]+\*ABS\*\+0x12345678
+[      ]+4:[   ]+R_AARCH64(|_P32)_ADD_ABS_LO12_NC[     ]+bar
 [      ]+8:[   ]+d65f03c0[     ]+ret
+#...
+0+010 <.*>:
+[      ]+10:[  ]+90000000[     ]+adrp[         ]+x0, [0-9]*[   ]+<.*>
+[      ]+10:[  ]+R_AARCH64(|_P32)_ADR_PREL_PG_HI21[    ]+\.text\+0x10
+[      ]+14:[  ]+91000000[     ]+add[  ]+x0, x0, #0x0
+[      ]+14:[  ]+R_AARCH64(|_P32)_ADD_ABS_LO12_NC[     ]+\.text\+0x10
+[      ]+18:[  ]+90000001[     ]+adrp[         ]+x1, [0-9]*[   ]+<.*>
+[      ]+18:[  ]+R_AARCH64(|_P32)_ADR_PREL_PG_HI21[    ]+\.text\+0x1c
+[      ]+1c:[  ]+91000021[     ]+add[  ]+x1, x1, #0x0
+[      ]+1c:[  ]+R_AARCH64(|_P32)_ADD_ABS_LO12_NC[     ]+\.text\+0x1c
+[      ]+20:[  ]+d65f03c0[     ]+ret
 #pass
index 8cb92309f35d9243ee0ff30d02128f61c73cb0a8..08aa64bb3d24f3a17ac62e83c92897c3580c7f27 100644 (file)
@@ -13,4 +13,13 @@ foo:
        add     x0, x0, :lo12:bar
        ret
        .size   foo, .-foo
-       .ident  "GCC: (GNU) 10.2.1 20201030 (RTEMS 6, RSB "
+
+       .p2align 4
+       .type   dot, %function
+dot:
+       adrp    x0, .
+       add     x0, x0, :lo12:. - 4
+       adrp    x1, . + 4
+       add     x1, x1, :lo12:.
+       ret
+       .size   dot, .-dot