This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC PATCH, binutils, ARM 4/11, ping] Use getters/setters to access ARM branch type


Hi Thomas,

>>>> -#define ARM_SYM_BRANCH_TYPE(SYM) \
>>>> -  ((enum arm_st_branch_type) (SYM)->st_target_internal)
>>>> +#define ARM_GET_SYM_BRANCH_TYPE(SYM_TARGET_INTERNAL) \
>>>> +  ((enum arm_st_branch_type) ((SYM_TARGET_INTERNAL) & 3))
>>>> +#define ARM_SET_SYM_BRANCH_TYPE(SYM_TARGET_INTERNAL,TYPE) \
>>>> +  ((SYM_TARGET_INTERNAL) = ((SYM_TARGET_INTERNAL) & ~3) | ((TYPE) & 3))
>>
>> It occurs to me that an out-of-range value for the TYPE parameter to the
>> ARM_SET_SYM_BRANCH_TYPE macro ought to be flagged as an error, and not
>> silently truncated.  You could probably let the compiler's enum checking do
>> this...
> 
> Any advice on how to catch any growth in terms of enum size? The point is for
> later commit [1] to start using currently unused bits but we need to make sure
> these new macros are updated if branch type enum increase in size.
> 
> [1] https://sourceware.org/ml/binutils/2016-03/msg00379.html

How about this ?  It is a bit complicated because I could not find a way to use
the compiler's enum checking to verify the bitfield size, so I had to use assertions
instead.  Still I think that it should work, and be relatively simple to extend as
necessary.

Cheers
  Nick


enum arm_st_branch_type
{
  ST_BRANCH_TO_ARM = 0,
  ST_BRANCH_TO_THUMB,
  ST_BRANCH_LONG,
  ST_BRANCH_UNKNOWN,
  ST_BRANCH_ENUM_SIZE
};

#define NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS  3
#define CMSE_BITFIELD                     (NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS + 1)
#define ENUM_ARM_ST_BRANCH_BITMASK        ((1 << NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS) - 1)
#define ARM_CMSE_SPCL_BITMASK             (1 << CMSE_BITFIELD)

#define ARM_SYM_BRANCH_TYPE(SYM) \
  ARM_GET_SYM_BRANCH_TYPE ((SYM)->st_target_internal)

#define ARM_GET_SYM_BRANCH_TYPE(STI) \
  ((enum arm_st_branch_type) (STI & ENUM_ARM_ST_BRANCH_BITMASK))

#ifdef BFD_ASSERT
#define ARM_SET_SYM_BRANCH_TYPE(STI, TYPE)		\
  do							\
    {							\
      unsigned typ = (TYPE);				\
      BFD_ASSERT (typ <= ST_BRANCH_ENUM_SIZE);		\
      BFD_ASSERT ((1 << NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS) >= ST_BRANCH_ENUM_SIZE); \
      (STI) &= ~ ENUM_ARM_ST_BRANCH_BITMASK;		\
      (STI) |= typ & ENUM_ARM_ST_BRANCH_BITMASK;	\
    }							\
  while (0)
#else
#define ARM_SET_SYM_BRANCH_TYPE(STI, TYPE)		\
  do							\
    {							\
      unsigned typ = (TYPE);				\
      (STI) &= ~ ENUM_ARM_ST_BRANCH_BITMASK;		\
      (STI) |= typ & ENUM_ARM_ST_BRANCH_BITMASK;	\
    }							\
  while (0)
#endif
  
/* Get or set whether a symbol is a special symbol of an entry function of 
   CMSE secure code.  */
#define ARM_GET_SYM_CMSE_SPCL(STI)			\
  (((STI) & ARM_CMSE_SPCL_BITMASK) ? 1 : 0)

#define ARM_SET_SYM_CMSE_SPCL(STI)			\
  do							\
    {							\
      (STI) |= ARM_CMSE_SPCL_BITMASK;			\
    }							\
  while (0)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]