target/armv7m,cortex_m: introduce checked arch_info cast routines

target_to_armv7m() and target_to_cm() do not match the magic number
so they are not suitable for use outside of target driver code.

Add checked versions of pointer getters. Match the magic number
to ensure the returned value points to struct of the correct type.

Change-Id: If90ef7e969ef04f0f2103e0da29dcbe8e1ac1c0d
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/6750
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Tomas Vanek 2021-11-24 22:11:13 +01:00
parent 10b5ac9ccb
commit e4ba76a003
2 changed files with 69 additions and 9 deletions

View File

@ -255,15 +255,48 @@ struct armv7m_common {
void (*pre_restore_context)(struct target *target);
};
static inline bool is_armv7m(const struct armv7m_common *armv7m)
{
return armv7m->common_magic == ARMV7M_COMMON_MAGIC;
}
/**
* @returns the pointer to the target specific struct
* without matching a magic number.
* Use in target specific service routines, where the correct
* type of arch_info is certain.
*/
static inline struct armv7m_common *
target_to_armv7m(struct target *target)
{
return container_of(target->arch_info, struct armv7m_common, arm);
}
static inline bool is_armv7m(const struct armv7m_common *armv7m)
/**
* @returns the pointer to the target specific struct
* or NULL if the magic number does not match.
* Use in a flash driver or any place where mismatch of the arch_info
* type can happen.
*/
static inline struct armv7m_common *
target_to_armv7m_safe(struct target *target)
{
return armv7m->common_magic == ARMV7M_COMMON_MAGIC;
if (!target)
return NULL;
if (!target->arch_info)
return NULL;
/* Check the parent type first to prevent peeking memory too far
* from arch_info pointer */
if (!is_arm(target_to_arm(target)))
return NULL;
struct armv7m_common *armv7m = target_to_armv7m(target);
if (!is_armv7m(armv7m))
return NULL;
return armv7m;
}
struct armv7m_algorithm {

View File

@ -247,13 +247,6 @@ struct cortex_m_common {
bool maskints_erratum;
};
static inline struct cortex_m_common *
target_to_cm(struct target *target)
{
return container_of(target->arch_info,
struct cortex_m_common, armv7m.arm);
}
static inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m)
{
return cortex_m->common_magic == CORTEX_M_COMMON_MAGIC;
@ -267,6 +260,40 @@ static inline bool is_cortex_m_with_dap_access(const struct cortex_m_common *cor
return !cortex_m->armv7m.is_hla_target;
}
/**
* @returns the pointer to the target specific struct
* without matching a magic number.
* Use in target specific service routines, where the correct
* type of arch_info is certain.
*/
static inline struct cortex_m_common *
target_to_cm(struct target *target)
{
return container_of(target->arch_info,
struct cortex_m_common, armv7m.arm);
}
/**
* @returns the pointer to the target specific struct
* or NULL if the magic number does not match.
* Use in a flash driver or any place where mismatch of the arch_info
* type can happen.
*/
static inline struct cortex_m_common *
target_to_cortex_m_safe(struct target *target)
{
/* Check the parent types first to prevent peeking memory too far
* from arch_info pointer */
if (!target_to_armv7m_safe(target))
return NULL;
struct cortex_m_common *cortex_m = target_to_cm(target);
if (!is_cortex_m_or_hla(cortex_m))
return NULL;
return cortex_m;
}
int cortex_m_examine(struct target *target);
int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint);
int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint);