]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: scfi: replace verbose expressions with local vars
authorIndu Bhagat <indu.bhagat@oracle.com>
Tue, 6 Aug 2024 16:46:06 +0000 (09:46 -0700)
committerIndu Bhagat <indu.bhagat@oracle.com>
Tue, 6 Aug 2024 16:46:06 +0000 (09:46 -0700)
Replace the scattered and repeated uses of verbose expressions with
variables.  E.g.,
  ginsn_get_src_reg (src1)  -> src1_reg
  ginsn_get_src_type (src1) -> src1_type
etc.

This hopefully makes the logic bit more maintainable.  While at it,
include minor adjustments to make few checks in gen_scfi_ops () more
precise:
  - When getting imm value from src operand, ensure the src type is
    GINSN_SRC_IMM,
  - When getting reg from src operand, ensure the src type is checked
    too (GINSN_SRC_REG or GINSN_SRC_INDIRECT as appropriate).

On the other hand, the changes in verify_heuristic_traceable_reg_fp ()
and verify_heuristic_traceable_stack_manipulation () are purely
mechanical.

gas/
        * scfi.c (verify_heuristic_traceable_reg_fp): Add new local
vars and reuse them.
        (verify_heuristic_traceable_stack_manipulation): Likewise.
        (gen_scfi_ops): Likewise.  Additionally, make some conditionals
more precise.

gas/scfi.c

index 5898a57b3306d2a1bb4a6da25948d4890975f565..6c59a8eeabc9a2aa19d50b325fa1b5913f595861 100644 (file)
@@ -478,14 +478,29 @@ verify_heuristic_traceable_reg_fp (ginsnS *ginsn, scfi_stateS *state)
 {
   /* The function uses this variable to issue error to user right away.  */
   int fp_traceable_p = 0;
-  struct ginsn_dst *dst;
+  enum ginsn_type gtype;
   struct ginsn_src *src1;
   struct ginsn_src *src2;
+  struct ginsn_dst *dst;
+  unsigned int src1_reg;
+  unsigned int dst_reg;
+  enum ginsn_src_type src1_type;
+  enum ginsn_src_type src2_type;
+  enum ginsn_dst_type dst_type;
+
+  gtype = ginsn->type;
 
   src1 = ginsn_get_src1 (ginsn);
   src2 = ginsn_get_src2 (ginsn);
   dst = ginsn_get_dst (ginsn);
 
+  src1_reg = ginsn_get_src_reg (src1);
+  dst_reg = ginsn_get_dst_reg (dst);
+
+  src1_type = ginsn_get_src_type (src1);
+  src2_type = ginsn_get_src_type (src2);
+  dst_type = ginsn_get_dst_type (dst);
+
   /* Stack manipulation can be done in a variety of ways.  A program may
      allocate stack statically or may perform dynamic stack allocation in
      the prologue.
@@ -498,25 +513,26 @@ verify_heuristic_traceable_reg_fp (ginsnS *ginsn, scfi_stateS *state)
 
   /* Check all applicable instructions with dest REG_FP, when the CFA base
      register is REG_FP.  */
-  if (state->regs[REG_CFA].base == REG_FP && ginsn_get_dst_reg (dst) == REG_FP)
+  if (state->regs[REG_CFA].base == REG_FP
+      && (dst_type == GINSN_DST_REG || dst_type == GINSN_DST_INDIRECT)
+      && dst_reg == REG_FP)
     {
       /* Excuse the add/sub with imm usage: They are OK.  */
-      if ((ginsn->type == GINSN_TYPE_ADD || ginsn->type == GINSN_TYPE_SUB)
-         && ginsn_get_src_reg (src1) == REG_FP
-         && ginsn_get_src_type (src2) == GINSN_SRC_IMM)
+      if ((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB)
+         && src1_type == GINSN_SRC_REG && src1_reg == REG_FP
+         && src2_type == GINSN_SRC_IMM)
        fp_traceable_p = 0;
       /* REG_FP restore is OK too.  */
       else if (ginsn->type == GINSN_TYPE_LOAD)
        fp_traceable_p = 0;
       /* mov's to memory with REG_FP base do not make REG_FP untraceable.  */
-      else if (ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
-              && (ginsn->type == GINSN_TYPE_MOV
-                  || ginsn->type == GINSN_TYPE_STORE))
+      else if (dst_type == GINSN_DST_INDIRECT
+              && (gtype == GINSN_TYPE_MOV || gtype == GINSN_TYPE_STORE))
        fp_traceable_p = 0;
       /* Manipulations of the values possibly on stack are OK too.  */
-      else if ((ginsn->type == GINSN_TYPE_ADD || ginsn->type == GINSN_TYPE_SUB
-               || ginsn->type == GINSN_TYPE_AND)
-              && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT)
+      else if ((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB
+               || gtype == GINSN_TYPE_AND)
+              && dst_type == GINSN_DST_INDIRECT)
        fp_traceable_p = 0;
       /* All other ginsns with REG_FP as destination make REG_FP not
         traceable.  */
@@ -538,14 +554,29 @@ verify_heuristic_traceable_stack_manipulation (ginsnS *ginsn,
   /* The function uses this variable to issue error to user right away.  */
   int sp_untraceable_p = 0;
   bool possibly_untraceable = false;
+  enum ginsn_type gtype;
   struct ginsn_dst *dst;
   struct ginsn_src *src1;
   struct ginsn_src *src2;
+  unsigned int src1_reg;
+  unsigned int dst_reg;
+  enum ginsn_src_type src1_type;
+  enum ginsn_src_type src2_type;
+  enum ginsn_dst_type dst_type;
+
+  gtype = ginsn->type;
 
   src1 = ginsn_get_src1 (ginsn);
   src2 = ginsn_get_src2 (ginsn);
   dst = ginsn_get_dst (ginsn);
 
+  src1_reg = ginsn_get_src_reg (src1);
+  dst_reg = ginsn_get_dst_reg (dst);
+
+  src1_type = ginsn_get_src_type (src1);
+  src2_type = ginsn_get_src_type (src2);
+  dst_type = ginsn_get_dst_type (dst);
+
   /* Stack manipulation can be done in a variety of ways.  A program may
      allocate stack statically in prologue or may need to do dynamic stack
      allocation.
@@ -559,31 +590,24 @@ verify_heuristic_traceable_stack_manipulation (ginsnS *ginsn,
        amount of stack usage (and hence, the value of rsp) must be known at
        all times.  */
 
-  if (ginsn->type == GINSN_TYPE_MOV
-      && ginsn_get_dst_type (dst) == GINSN_DST_REG
-      && ginsn_get_dst_reg (dst) == REG_SP
-      && ginsn_get_src_type (src1) == GINSN_SRC_REG
+  if (gtype == GINSN_TYPE_MOV
+      && dst_type == GINSN_DST_REG && dst_reg == REG_SP
       /* Exclude mov %rbp, %rsp from this check.  */
-      && ginsn_get_src_reg (src1) != REG_FP)
+      && src1_type == GINSN_SRC_REG && src1_reg != REG_FP)
     {
-      /* mov %reg, %rsp.  */
       /* A previous mov %rsp, %reg must have been seen earlier for this to be
         an OK for stack manipulation.  */
-      if (state->scratch[ginsn_get_src_reg (src1)].base != REG_CFA
-         || state->scratch[ginsn_get_src_reg (src1)].state != CFI_IN_REG)
-       {
-         possibly_untraceable = true;
-       }
+      if (state->scratch[src1_reg].base != REG_CFA
+         || state->scratch[src1_reg].state != CFI_IN_REG)
+       possibly_untraceable = true;
     }
   /* Check add/sub/and insn usage when CFA base register is REG_SP.
      Any stack size manipulation, including stack realignment is not allowed
      if CFA base register is REG_SP.  */
-  else if (ginsn_get_dst_type (dst) == GINSN_DST_REG
-          && ginsn_get_dst_reg (dst) == REG_SP
-          && (((ginsn->type == GINSN_TYPE_ADD || ginsn->type == GINSN_TYPE_SUB)
-               && ginsn_get_src_type (src2) != GINSN_SRC_IMM)
-              || ginsn->type == GINSN_TYPE_AND
-              || ginsn->type == GINSN_TYPE_OTHER))
+  else if (dst_type == GINSN_DST_REG && dst_reg == REG_SP
+          && (((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB)
+               && src2_type != GINSN_SRC_IMM)
+              || gtype == GINSN_TYPE_AND || gtype == GINSN_TYPE_OTHER))
     possibly_untraceable = true;
   /* If a register save operation is seen when REG_SP is untraceable,
      CFI cannot be synthesized for register saves, hence bail out.  */
@@ -593,19 +617,15 @@ verify_heuristic_traceable_stack_manipulation (ginsnS *ginsn,
       /* If, however, the register save is an REG_FP-based, indirect mov
         like: mov reg, disp(%rbp) and CFA base register is REG_BP,
         untraceable REG_SP is not a problem.  */
-      if (ginsn->type == GINSN_TYPE_MOV
-         && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
-         && (ginsn_get_dst_reg (dst) == REG_FP
-             && state->regs[REG_CFA].base == REG_FP))
+      if (gtype == GINSN_TYPE_MOV && state->regs[REG_CFA].base == REG_FP
+         && dst_type == GINSN_DST_INDIRECT && dst_reg == REG_FP)
        sp_untraceable_p = 0;
     }
   else if (ginsn_scfi_restore_reg_p (ginsn, state) && !state->traceable_p)
     {
-      if (ginsn->type == GINSN_TYPE_MOV
-         && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
-         && (ginsn_get_src_reg (src1) == REG_SP
-             || (ginsn_get_src_reg (src1) == REG_FP
-                 && state->regs[REG_CFA].base != REG_FP)))
+      if (gtype == GINSN_TYPE_MOV && dst_type == GINSN_DST_INDIRECT
+         && (src1_reg == REG_SP
+             || (src1_reg == REG_FP && state->regs[REG_CFA].base != REG_FP)))
        sp_untraceable_p = 1;
     }
 
@@ -706,6 +726,11 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
   struct ginsn_src *src1;
   struct ginsn_src *src2;
   struct ginsn_dst *dst;
+  unsigned int src1_reg;
+  unsigned int dst_reg;
+  enum ginsn_src_type src1_type;
+  enum ginsn_src_type src2_type;
+  enum ginsn_dst_type dst_type;
 
   if (!ginsn || !state)
     ret = 1;
@@ -724,6 +749,13 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
   src2 = ginsn_get_src2 (ginsn);
   dst = ginsn_get_dst (ginsn);
 
+  src1_reg = ginsn_get_src_reg (src1);
+  dst_reg = ginsn_get_dst_reg (dst);
+
+  src1_type = ginsn_get_src_type (src1);
+  src2_type = ginsn_get_src_type (src2);
+  dst_type = ginsn_get_dst_type (dst);
+
   ret = verify_heuristic_traceable_stack_manipulation (ginsn, state);
   if (ret)
     return ret;
@@ -732,68 +764,63 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
   if (ret)
     return ret;
 
-  switch (ginsn->dst.type)
+  switch (dst_type)
     {
     case GINSN_DST_REG:
       switch (ginsn->type)
        {
        case GINSN_TYPE_MOV:
-         if (ginsn_get_src_type (src1) == GINSN_SRC_REG
-             && ginsn_get_src_reg (src1) == REG_SP
-             && ginsn_get_dst_reg (dst) == REG_FP
+         if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
+             && dst_type == GINSN_DST_REG && dst_reg == REG_FP
              && state->regs[REG_CFA].base == REG_SP)
            {
              /* mov %rsp, %rbp.  */
-             scfi_op_add_def_cfa_reg (state, ginsn, ginsn_get_dst_reg (dst));
+             scfi_op_add_def_cfa_reg (state, ginsn, dst_reg);
            }
-         else if (ginsn_get_src_type (src1) == GINSN_SRC_REG
-                  && ginsn_get_src_reg (src1) == REG_FP
-                  && ginsn_get_dst_reg (dst) == REG_SP
+         else if (src1_type == GINSN_SRC_REG && src1_reg == REG_FP
+                  && dst_type == GINSN_DST_REG && dst_reg == REG_SP
                   && state->regs[REG_CFA].base == REG_FP)
            {
              /* mov %rbp, %rsp.  */
              state->stack_size = -state->regs[REG_FP].offset;
-             scfi_op_add_def_cfa_reg (state, ginsn, ginsn_get_dst_reg (dst));
+             scfi_op_add_def_cfa_reg (state, ginsn, dst_reg);
              state->traceable_p = true;
            }
-         else if (ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
-                  && (ginsn_get_src_reg (src1) == REG_SP
-                      || ginsn_get_src_reg (src1) == REG_FP)
-                  && ginsn_track_reg_p (ginsn_get_dst_reg (dst), GINSN_GEN_SCFI))
+         else if (src1_type == GINSN_SRC_INDIRECT
+                  && (src1_reg == REG_SP || src1_reg == REG_FP)
+                  && ginsn_track_reg_p (dst_reg, GINSN_GEN_SCFI))
            {
              /* mov disp(%rsp), reg.  */
              /* mov disp(%rbp), reg.  */
              if (verify_heuristic_symmetrical_restore_reg (state, ginsn))
                {
-                 scfi_state_restore_reg (state, ginsn_get_dst_reg (dst));
-                 scfi_op_add_cfa_restore (ginsn, ginsn_get_dst_reg (dst));
+                 scfi_state_restore_reg (state, dst_reg);
+                 scfi_op_add_cfa_restore (ginsn, dst_reg);
                }
              else
                as_warn_where (ginsn->file, ginsn->line,
                               _("SCFI: asymetrical register restore"));
            }
-         else if (ginsn_get_src_type (src1) == GINSN_SRC_REG
-                  && ginsn_get_dst_type (dst) == GINSN_DST_REG
-                  && ginsn_get_src_reg (src1) == REG_SP)
+         else if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
+                  && dst_type == GINSN_DST_REG)
            {
              /* mov %rsp, %reg.  */
              /* The value of rsp is taken directly from state->stack_size.
                 IMP: The workflow in gen_scfi_ops must keep it updated.
                 PS: Not taking the value from state->scratch[REG_SP] is
                 intentional.  */
-             state->scratch[ginsn_get_dst_reg (dst)].base = REG_CFA;
-             state->scratch[ginsn_get_dst_reg (dst)].offset = -state->stack_size;
-             state->scratch[ginsn_get_dst_reg (dst)].state = CFI_IN_REG;
+             state->scratch[dst_reg].base = REG_CFA;
+             state->scratch[dst_reg].offset = -state->stack_size;
+             state->scratch[dst_reg].state = CFI_IN_REG;
            }
-         else if (ginsn_get_src_type (src1) == GINSN_SRC_REG
-                  && ginsn_get_dst_type (dst) == GINSN_DST_REG
-                  && ginsn_get_dst_reg (dst) == REG_SP)
+         else if (src1_type == GINSN_SRC_REG
+                  && dst_type == GINSN_DST_REG && dst_reg == REG_SP)
            {
              /* mov %reg, %rsp.  */
              /* Keep the value of REG_SP updated.  */
-             if (state->scratch[ginsn_get_src_reg (src1)].state == CFI_IN_REG)
+             if (state->scratch[src1_reg].state == CFI_IN_REG)
                {
-                 state->stack_size = -state->scratch[ginsn_get_src_reg (src1)].offset;
+                 state->stack_size = -state->scratch[src1_reg].offset;
                  state->traceable_p = true;
                }
 # if 0
@@ -805,8 +832,9 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
            }
          break;
        case GINSN_TYPE_SUB:
-         if (ginsn_get_src_reg (src1) == REG_SP
-             && ginsn_get_dst_reg (dst) == REG_SP)
+         if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
+             && dst_type == GINSN_DST_REG && dst_reg == REG_SP
+             && src2_type == GINSN_SRC_IMM)
            {
              /* Stack inc/dec offset, when generated due to stack push and pop is
                 target-specific.  Use the value encoded in the ginsn.  */
@@ -819,8 +847,9 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
            }
          break;
        case GINSN_TYPE_ADD:
-         if (ginsn_get_src_reg (src1) == REG_SP
-             && ginsn_get_dst_reg (dst) == REG_SP)
+         if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
+             && dst_type == GINSN_DST_REG && dst_reg == REG_SP
+             && src2_type == GINSN_SRC_IMM)
            {
              /* Stack inc/dec offset is target-specific.  Use the value
                 encoded in the ginsn.  */
@@ -832,8 +861,8 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
                  scfi_op_add_cfa_offset_inc (state, ginsn, ginsn_get_src_imm (src2));
                }
            }
-         else if (ginsn_get_src_reg (src1) == REG_FP
-                  && ginsn_get_dst_reg (dst) == REG_SP
+         else if (src1_type == GINSN_SRC_REG && src1_reg == REG_FP
+                  && dst_type == GINSN_DST_REG && dst_reg == REG_SP
                   && state->regs[REG_CFA].base == REG_FP)
            {
              /* FIXME - what is this for ? */
@@ -842,26 +871,25 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
          break;
        case GINSN_TYPE_LOAD:
          /* If this is a load from stack.  */
-         if (ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
-             && (ginsn_get_src_reg (src1) == REG_SP
-                 || (ginsn_get_src_reg (src1) == REG_FP
-                     && state->regs[REG_CFA].base == REG_FP)))
+         if (src1_type == GINSN_SRC_INDIRECT
+             && ((src1_reg == REG_FP && state->regs[REG_CFA].base == REG_FP)
+                 || src1_reg == REG_SP))
+
            {
              /* pop %rbp when CFA tracking is REG_FP based.  */
-             if (ginsn_get_dst_reg (dst) == REG_FP
-                 && state->regs[REG_CFA].base == REG_FP)
+             if (dst_reg == REG_FP && state->regs[REG_CFA].base == REG_FP)
                {
                  scfi_op_add_def_cfa_reg (state, ginsn, REG_SP);
                  if (state->regs[REG_CFA].offset != state->stack_size)
                    scfi_op_add_cfa_offset_inc (state, ginsn,
                                                (state->regs[REG_CFA].offset - state->stack_size));
                }
-             if (ginsn_track_reg_p (ginsn_get_dst_reg (dst), GINSN_GEN_SCFI))
+             if (ginsn_track_reg_p (dst_reg, GINSN_GEN_SCFI))
                {
                  if (verify_heuristic_symmetrical_restore_reg (state, ginsn))
                    {
-                     scfi_state_restore_reg (state, ginsn_get_dst_reg (dst));
-                     scfi_op_add_cfa_restore (ginsn, ginsn_get_dst_reg (dst));
+                     scfi_state_restore_reg (state, dst_reg);
+                     scfi_op_add_cfa_restore (ginsn, dst_reg);
                    }
                  else
                    as_warn_where (ginsn->file, ginsn->line,
@@ -890,20 +918,20 @@ gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
       /* mov reg, disp(%rsp) */
       if (ginsn_scfi_save_reg_p (ginsn, state))
        {
-         if (ginsn_get_dst_reg (dst) == REG_SP)
+         if (dst_reg == REG_SP)
            {
              /* mov reg, disp(%rsp) */
              offset = 0 - state->stack_size + ginsn_get_dst_disp (dst);
-             scfi_state_save_reg (state, ginsn_get_src_reg (src1), REG_CFA, offset);
-             scfi_op_add_cfi_offset (state, ginsn, ginsn_get_src_reg (src1));
+             scfi_state_save_reg (state, src1_reg, REG_CFA, offset);
+             scfi_op_add_cfi_offset (state, ginsn, src1_reg);
            }
-         else if (ginsn_get_dst_reg (dst) == REG_FP)
+         else if (dst_reg == REG_FP)
            {
              gas_assert (state->regs[REG_CFA].base == REG_FP);
              /* mov reg, disp(%rbp) */
              offset = 0 - state->regs[REG_CFA].offset + ginsn_get_dst_disp (dst);
-             scfi_state_save_reg (state, ginsn_get_src_reg (src1), REG_CFA, offset);
-             scfi_op_add_cfi_offset (state, ginsn, ginsn_get_src_reg (src1));
+             scfi_state_save_reg (state, src1_reg, REG_CFA, offset);
+             scfi_op_add_cfi_offset (state, ginsn, src1_reg);
            }
        }
       break;