From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by sourceware.org (Postfix) with ESMTPS id BE9623858D28 for ; Fri, 4 Feb 2022 08:42:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BE9623858D28 Received: by mail-wr1-x436.google.com with SMTP id j16so9848603wrd.8 for ; Fri, 04 Feb 2022 00:42:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vnz2wz0QyVq8bnwZWAAJx7TLGdnb04tUFL4F4tQvDWU=; b=KxL8a93qPXXiXngPfBeRXfquPSuCeHuN7msADZ7HObAJ5vFmeOvTMhgxqObveyZfvA qQSypRgXmqJ37Myt7bWRKdDIbW3xHbM5+S6di+2X14oE5JPxOP+GL38IEvBUL2MJ2E1U /jnHAlfdJo1a+ytWHftGH8JHXhhII5wZeiutzI2EIsTO1JkE2cT1mK8yF0y93wgOqKeS RbZMtxKgJUUNOthm0E41CpMTWU/GwoqaF/hQFZveyokDz8Rjwe9v+irsVve5AsXBTlDY tV+N3OAQb2cQvgons7GX2GisqyZuRB38dK3b8YuR1UuY6enX9Or89O1n33Vn5w7a+Tod r+Cg== X-Gm-Message-State: AOAM531/rvY6hTczuteHPYCUgq1iYeBP8lnppr5upbXnJNt1uOKFrqHC XayLP+aQuCclHNlfswaMi0G4v/zP7LddqQ== X-Google-Smtp-Source: ABdhPJyJbLRzoOlJlDogY1yTYzlBpG0BF1SGjV8w9YAsjpHLNOiiZd43m66V5qQVtcQ5ov7CcUz0vg== X-Received: by 2002:adf:e48f:: with SMTP id i15mr1556678wrm.347.1643964120412; Fri, 04 Feb 2022 00:42:00 -0800 (PST) Received: from babel.clyon.hd.free.fr ([2a01:e0a:203:b210:afd3:bde6:6149:fc73]) by smtp.gmail.com with ESMTPSA id y7sm1198617wrr.74.2022.02.04.00.41.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Feb 2022 00:41:59 -0800 (PST) From: christophe.lyon.oss@gmail.com X-Google-Original-From: christophe.lyon@gmail.com To: gdb-patches@sourceware.org Cc: torbjorn.svensson@st.com, Christophe Lyon Subject: [PATCH v3 4/5] gdb/arm: Add support for multiple stack pointers on Cortex-M Date: Fri, 4 Feb 2022 09:41:50 +0100 Message-Id: <20220204084151.14480-5-christophe.lyon@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220204084151.14480-1-christophe.lyon@gmail.com> References: <20220204084151.14480-1-christophe.lyon@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Feb 2022 08:42:05 -0000 From: Christophe Lyon V8-M architecture with Security extension features four stack pointers to handle Secure and Non-secure modes. This patch adds support to switch between them as needed during unwinding, and replaces all updates of cache->prev_sp with calls to arm_cache_set_prev_sp. Signed-off-by: Torbjorn Svensson Signed-off-by: Christophe Lyon --- gdb/arm-tdep.c | 257 +++++++++++++++++++++++++++++--- gdb/arm-tdep.h | 11 +- gdb/features/arm/arm-secext.c | 17 +++ gdb/features/arm/arm-secext.xml | 15 ++ 4 files changed, 279 insertions(+), 21 deletions(-) create mode 100644 gdb/features/arm/arm-secext.c create mode 100644 gdb/features/arm/arm-secext.xml diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 18b7c18d3cc..79c4cc6206f 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -275,7 +275,21 @@ struct arm_prologue_cache /* The stack pointer at the time this frame was created; i.e. the caller's stack pointer when this function was called. It is used to identify this frame. */ - CORE_ADDR prev_sp; + CORE_ADDR sp; + + /* Additional stack pointers used by M-profile with Security extension. */ + /* Use msp_s / psp_s to hold the values of msp / psp when there is + no Security extension. */ + CORE_ADDR msp_s; + CORE_ADDR msp_ns; + CORE_ADDR psp_s; + CORE_ADDR psp_ns; + + /* Active stack pointer. */ + int active_sp_regnum; + + bool have_sec_ext; + bool is_m; /* The frame base for this frame is just prev_sp - frame size. FRAMESIZE is the distance from the frame pointer to the @@ -293,6 +307,10 @@ struct arm_prologue_cache static void arm_cache_init (struct arm_prologue_cache *cache, struct gdbarch *gdbarch) { + cache->have_sec_ext = false; + cache->is_m = false; + cache->active_sp_regnum = ARM_SP_REGNUM; + cache->framesize = 0; cache->framereg = 0; cache->saved_regs = trad_frame_alloc_saved_regs (gdbarch); @@ -302,9 +320,131 @@ static void arm_cache_init (struct arm_prologue_cache *cache, struct frame_info *frame) { struct gdbarch *gdbarch = get_frame_arch (frame); - cache->prev_sp = get_frame_register_unsigned (frame, ARM_SP_REGNUM); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); + cache->sp = get_frame_register_unsigned (frame, ARM_SP_REGNUM); arm_cache_init (cache, gdbarch); + + cache->have_sec_ext = tdep->have_sec_ext; + cache->is_m = tdep->is_m; + + /* Initialize stack pointers, and flag the active one. */ +#define INIT_ARM_CACHE_SP(regnum, member) do { \ + CORE_ADDR val = get_frame_register_unsigned (frame, (regnum)); \ + if (val == cache->sp) \ + { \ + cache->active_sp_regnum = (regnum); \ + } \ + (member) = val; \ + } while (0) + + if (tdep->have_sec_ext) + { + INIT_ARM_CACHE_SP (tdep->m_profile_msp_s_regnum, cache->msp_s); + INIT_ARM_CACHE_SP (tdep->m_profile_psp_s_regnum, cache->psp_s); + INIT_ARM_CACHE_SP (tdep->m_profile_msp_ns_regnum, cache->msp_ns); + INIT_ARM_CACHE_SP (tdep->m_profile_psp_ns_regnum, cache->psp_ns); + /* Use MSP_S as default stack pointer. */ + if (cache->active_sp_regnum == ARM_SP_REGNUM) + cache->active_sp_regnum = tdep->m_profile_msp_s_regnum; + } + else if (tdep->is_m) + { + INIT_ARM_CACHE_SP (tdep->m_profile_msp_regnum, cache->msp_s); + INIT_ARM_CACHE_SP (tdep->m_profile_psp_regnum, cache->psp_s); + } + else + { + INIT_ARM_CACHE_SP (ARM_SP_REGNUM, cache->msp_s); + } + #undef INIT_ARM_CACHE_SP +} + +static gdb::optional +arm_cache_get_sp_register (struct arm_prologue_cache *cache, arm_gdbarch_tdep *tdep, int regnum) +{ + if (cache->have_sec_ext) + { + if (regnum == tdep->m_profile_msp_s_regnum) + return cache->msp_s; + if (regnum == tdep->m_profile_msp_ns_regnum) + return cache->msp_ns; + if (regnum == tdep->m_profile_psp_s_regnum) + return cache->psp_s; + if (regnum == tdep->m_profile_psp_ns_regnum) + return cache->psp_ns; + if (regnum == ARM_SP_REGNUM) + return cache->sp; + } + else if (cache->is_m) + { + if (regnum == tdep->m_profile_msp_regnum) + return cache->msp_s; + if (regnum == tdep->m_profile_psp_regnum) + return cache->psp_s; + if (regnum == ARM_SP_REGNUM) + return cache->sp; + } + else + { + if (regnum == ARM_SP_REGNUM) + return cache->sp; + } + return {}; +} + +static CORE_ADDR +arm_cache_get_prev_sp (struct arm_prologue_cache *cache, arm_gdbarch_tdep *tdep) +{ + gdb::optional val + = arm_cache_get_sp_register (cache, tdep, cache->active_sp_regnum); + if (val.has_value ()) + return *val; + + gdb_assert_not_reached ("Invalid SP selection"); + return 0; +} + +static void +arm_cache_set_prev_sp (struct arm_prologue_cache *cache, arm_gdbarch_tdep *tdep, CORE_ADDR val) +{ + if (cache->have_sec_ext) + { + if (cache->active_sp_regnum == tdep->m_profile_msp_s_regnum) + cache->msp_s = val; + else if (cache->active_sp_regnum == tdep->m_profile_msp_ns_regnum) + cache->msp_ns = val; + else if (cache->active_sp_regnum == tdep->m_profile_psp_s_regnum) + cache->psp_s = val; + else if (cache->active_sp_regnum == tdep->m_profile_psp_ns_regnum) + cache->psp_ns = val; + else if (cache->active_sp_regnum == ARM_SP_REGNUM) + cache->sp = val; + + return; + } + else if (cache->is_m) + { + if (cache->active_sp_regnum == tdep->m_profile_msp_regnum) + cache->msp_s = val; + else if (cache->active_sp_regnum == tdep->m_profile_psp_regnum) + cache->psp_s = val; + else if (cache->active_sp_regnum == ARM_SP_REGNUM) + cache->sp = val; + + return; + } + else + { + switch (cache->active_sp_regnum) + { + case ARM_SP_REGNUM: + cache->sp = val; + return; + } + } + + gdb_assert_not_reached ("Invalid SP selection"); } namespace { @@ -1951,14 +2091,17 @@ arm_make_prologue_cache (struct frame_info *this_frame) if (unwound_fp == 0) return cache; - cache->prev_sp = unwound_fp + cache->framesize; + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + + arm_cache_set_prev_sp (cache, tdep, unwound_fp + cache->framesize); /* Calculate actual addresses of saved registers using offsets determined by arm_scan_prologue. */ for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++) if (cache->saved_regs[reg].is_addr ()) cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr () - + cache->prev_sp); + + arm_cache_get_prev_sp (cache, tdep)); return cache; } @@ -1984,7 +2127,7 @@ arm_prologue_unwind_stop_reason (struct frame_info *this_frame, return UNWIND_OUTERMOST; /* If we've hit a wall, stop. */ - if (cache->prev_sp == 0) + if (arm_cache_get_prev_sp (cache, tdep) == 0) return UNWIND_OUTERMOST; return UNWIND_NO_REASON; @@ -2006,6 +2149,9 @@ arm_prologue_this_id (struct frame_info *this_frame, *this_cache = arm_make_prologue_cache (this_frame); cache = (struct arm_prologue_cache *) *this_cache; + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + /* Use function start address as part of the frame ID. If we cannot identify the start address (due to missing symbol information), fall back to just using the current PC. */ @@ -2014,7 +2160,7 @@ arm_prologue_this_id (struct frame_info *this_frame, if (!func) func = pc; - id = frame_id_build (cache->prev_sp, func); + id = frame_id_build (arm_cache_get_prev_sp (cache, tdep), func); *this_id = id; } @@ -2024,6 +2170,7 @@ arm_prologue_prev_register (struct frame_info *this_frame, int prev_regnum) { struct gdbarch *gdbarch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); struct arm_prologue_cache *cache; if (*this_cache == NULL) @@ -2048,7 +2195,8 @@ arm_prologue_prev_register (struct frame_info *this_frame, identified by the next frame's stack pointer at the time of the call. The value was already reconstructed into PREV_SP. */ if (prev_regnum == ARM_SP_REGNUM) - return frame_unwind_got_constant (this_frame, prev_regnum, cache->prev_sp); + return frame_unwind_got_constant (this_frame, prev_regnum, + arm_cache_get_prev_sp (cache, tdep)); /* The CPSR may have been changed by the call instruction and by the called function. The only bit we can reconstruct is the T bit, @@ -2686,7 +2834,9 @@ arm_exidx_fill_cache (struct frame_info *this_frame, gdb_byte *entry) = vsp - get_frame_register_unsigned (this_frame, cache->framereg); /* We already got the previous SP. */ - cache->prev_sp = vsp; + struct gdbarch *gdbarch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); + arm_cache_set_prev_sp (cache, tdep, vsp); return cache; } @@ -2809,14 +2959,16 @@ arm_make_epilogue_frame_cache (struct frame_info *this_frame) arm_scan_prologue (this_frame, cache); /* Since we are in epilogue, the SP has been restored. */ - cache->prev_sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM); + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + arm_cache_set_prev_sp (cache, tdep, get_frame_register_unsigned (this_frame, ARM_SP_REGNUM)); /* Calculate actual addresses of saved registers using offsets determined by arm_scan_prologue. */ for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++) if (cache->saved_regs[reg].is_addr ()) cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr () - + cache->prev_sp); + + arm_cache_get_prev_sp (cache, tdep)); return cache; } @@ -2844,7 +2996,9 @@ arm_epilogue_frame_this_id (struct frame_info *this_frame, if (func == 0) func = pc; - (*this_id) = frame_id_build (cache->prev_sp, pc); + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + (*this_id) = frame_id_build (arm_cache_get_prev_sp (cache, tdep), pc); } /* Implementation of function hook 'prev_register' in @@ -2966,7 +3120,9 @@ arm_make_stub_cache (struct frame_info *this_frame) cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache); arm_cache_init (cache, this_frame); - cache->prev_sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM); + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + arm_cache_set_prev_sp (cache, tdep, get_frame_register_unsigned (this_frame, ARM_SP_REGNUM)); return cache; } @@ -2984,7 +3140,9 @@ arm_stub_this_id (struct frame_info *this_frame, *this_cache = arm_make_stub_cache (this_frame); cache = (struct arm_prologue_cache *) *this_cache; - *this_id = frame_id_build (cache->prev_sp, get_frame_pc (this_frame)); + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + *this_id = frame_id_build (arm_cache_get_prev_sp (cache, tdep), get_frame_pc (this_frame)); } static int @@ -3105,12 +3263,12 @@ arm_m_exception_cache (struct frame_info *this_frame) cache->saved_regs[ARM_FPSCR_REGNUM].set_addr (unwound_sp + 0x60); /* Offset 0x64 is reserved. */ - cache->prev_sp = unwound_sp + 0x68; + arm_cache_set_prev_sp (cache, tdep, unwound_sp + 0x68); } else { /* Standard stack frame type used. */ - cache->prev_sp = unwound_sp + 0x20; + arm_cache_set_prev_sp (cache, tdep, unwound_sp + 0x20); } /* Check EXC_RETURN bit S if Secure or Non-secure stack used. */ @@ -3132,7 +3290,7 @@ arm_m_exception_cache (struct frame_info *this_frame) previous context's stack pointer. */ if (safe_read_memory_integer (unwound_sp + 28, 4, byte_order, &xpsr) && (xpsr & (1 << 9)) != 0) - cache->prev_sp += 4; + arm_cache_set_prev_sp (cache, tdep, arm_cache_get_prev_sp (cache, tdep) + 4); return cache; } @@ -3152,7 +3310,9 @@ arm_m_exception_this_id (struct frame_info *this_frame, cache = (struct arm_prologue_cache *) *this_cache; /* Our frame ID for a stub frame is the current SP and LR. */ - *this_id = frame_id_build (cache->prev_sp, + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + *this_id = frame_id_build (arm_cache_get_prev_sp (cache, tdep), get_frame_pc (this_frame)); } @@ -3171,9 +3331,11 @@ arm_m_exception_prev_register (struct frame_info *this_frame, cache = (struct arm_prologue_cache *) *this_cache; /* The value was already reconstructed into PREV_SP. */ + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); if (prev_regnum == ARM_SP_REGNUM) return frame_unwind_got_constant (this_frame, prev_regnum, - cache->prev_sp); + arm_cache_get_prev_sp (cache, tdep)); return trad_frame_get_prev_register (this_frame, cache->saved_regs, prev_regnum); @@ -3218,7 +3380,9 @@ arm_normal_frame_base (struct frame_info *this_frame, void **this_cache) *this_cache = arm_make_prologue_cache (this_frame); cache = (struct arm_prologue_cache *) *this_cache; - return cache->prev_sp - cache->framesize; + gdbarch *arch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch); + return arm_cache_get_prev_sp (cache, tdep) - cache->framesize; } struct frame_base arm_normal_base = { @@ -9084,6 +9248,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdesc_arch_data_up tdesc_data; int i; bool is_m = false; + bool have_sec_ext = false; int vfp_register_count = 0; bool have_s_pseudos = false, have_q_pseudos = false; bool have_wmmx_registers = false; @@ -9097,6 +9262,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) bool have_m_profile_sp = false; int m_profile_msp_regnum = -1; int m_profile_psp_regnum = -1; + int m_profile_msp_ns_regnum = -1; + int m_profile_psp_ns_regnum = -1; + int m_profile_msp_s_regnum = -1; + int m_profile_psp_s_regnum = -1; /* If we have an object to base this architecture on, try to determine its ABI. */ @@ -9469,6 +9638,43 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (have_vfp) have_q_pseudos = true; } + + /* Do we have the Security extension? */ + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.arm.secext"); + if (feature != nullptr) + { + /* Secure/Non-secure stack pointers. */ + /* MSP_NS */ + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + register_count, "msp_ns"); + if (valid_p) + m_profile_msp_ns_regnum = register_count++; + + /* PSP_NS */ + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + register_count, "psp_ns"); + if (valid_p) + m_profile_psp_ns_regnum = register_count++; + + /* MSP_S */ + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + register_count, "msp_s"); + if (valid_p) + m_profile_msp_s_regnum = register_count++; + + /* PSP_S */ + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + register_count, "psp_s"); + if (valid_p) + m_profile_psp_s_regnum = register_count++; + + if (!valid_p) + return nullptr; + + have_sec_ext = true; + } + } } @@ -9510,6 +9716,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->arm_abi = arm_abi; tdep->fp_model = fp_model; tdep->is_m = is_m; + tdep->have_sec_ext = have_sec_ext; tdep->have_fpa_registers = have_fpa_registers; tdep->have_wmmx_registers = have_wmmx_registers; gdb_assert (vfp_register_count == 0 @@ -9532,6 +9739,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { tdep->m_profile_msp_regnum = m_profile_msp_regnum; tdep->m_profile_psp_regnum = m_profile_psp_regnum; + tdep->m_profile_msp_ns_regnum = m_profile_msp_ns_regnum; + tdep->m_profile_psp_ns_regnum = m_profile_psp_ns_regnum; + tdep->m_profile_msp_s_regnum = m_profile_msp_s_regnum; + tdep->m_profile_psp_s_regnum = m_profile_psp_s_regnum; } arm_register_g_packet_guesses (gdbarch); @@ -9810,6 +10021,14 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) tdep->m_profile_msp_regnum); fprintf_unfiltered (file, _("arm_dump_tdep: m_profile_psp_regnum = %i\n"), tdep->m_profile_psp_regnum); + fprintf_unfiltered (file, _("arm_dump_tdep: m_profile_msp_ns_regnum = %i\n"), + tdep->m_profile_msp_ns_regnum); + fprintf_unfiltered (file, _("arm_dump_tdep: m_profile_psp_ns_regnum = %i\n"), + tdep->m_profile_psp_ns_regnum); + fprintf_unfiltered (file, _("arm_dump_tdep: m_profile_msp_s_regnum = %i\n"), + tdep->m_profile_msp_s_regnum); + fprintf_unfiltered (file, _("arm_dump_tdep: m_profile_psp_s_regnum = %i\n"), + tdep->m_profile_psp_s_regnum); fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"), (unsigned long) tdep->lowest_pc); } diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index 420af43a1fe..9019955c7d4 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -119,10 +119,17 @@ struct arm_gdbarch_tdep : gdbarch_tdep int mve_pseudo_base = 0; /* Number of the first MVE pseudo register. */ int mve_pseudo_count = 0; /* Total number of MVE pseudo registers. */ - int m_profile_msp_regnum = 0; /* M-profile MSP register number. */ - int m_profile_psp_regnum = 0; /* M-profile PSP register number. */ + int m_profile_msp_regnum = ARM_SP_REGNUM; /* M-profile MSP register number. */ + int m_profile_psp_regnum = ARM_SP_REGNUM; /* M-profile PSP register number. */ + + /* Secure and Non-secure stack pointers with security extension. */ + int m_profile_msp_ns_regnum = ARM_SP_REGNUM; /* M-profile MSP_NS register number. */ + int m_profile_psp_ns_regnum = ARM_SP_REGNUM; /* M-profile PSP_NS register number. */ + int m_profile_msp_s_regnum = ARM_SP_REGNUM; /* M-profile MSP_S register number. */ + int m_profile_psp_s_regnum = ARM_SP_REGNUM; /* M-profile PSP_S register number. */ bool is_m = false; /* Does the target follow the "M" profile. */ + bool have_sec_ext = false; /* Do we have secure extensions? */ CORE_ADDR lowest_pc = 0; /* Lowest address at which instructions will appear. */ diff --git a/gdb/features/arm/arm-secext.c b/gdb/features/arm/arm-secext.c new file mode 100644 index 00000000000..39ef4afb05f --- /dev/null +++ b/gdb/features/arm/arm-secext.c @@ -0,0 +1,17 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: arm-secext.xml */ + +#include "gdbsupport/tdesc.h" + +static int +create_feature_arm_arm_m_system (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.secext"); + tdesc_create_reg (feature, "msp_ns", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "psp_ns", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "msp_s", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "psp_s", regnum++, 1, NULL, 32, "data_ptr"); + return regnum; +} diff --git a/gdb/features/arm/arm-secext.xml b/gdb/features/arm/arm-secext.xml new file mode 100644 index 00000000000..52b2c20a982 --- /dev/null +++ b/gdb/features/arm/arm-secext.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + -- 2.25.1