diff --git a/src/target/armv7m.h b/src/target/armv7m.h index d33e57492..9ac121ac3 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -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 { diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index cabe405ce..8fb34f46c 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -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);