diff options
Diffstat (limited to 'gdb/i386-tdep.c')
-rw-r--r-- | gdb/i386-tdep.c | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 21a5a28..d3ad402 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -61,7 +61,6 @@ #include "stap-probe.h" #include "user-regs.h" #include "expression.h" -#include <ctype.h> #include <algorithm> #include <unordered_set> #include "producer.h" @@ -897,6 +896,22 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch, displaced_debug_printf ("relocated return addr at %s to %s", paddress (gdbarch, esp), paddress (gdbarch, retaddr)); + + /* If shadow stack is enabled, we need to correct the return address + on the shadow stack too. */ + bool shadow_stack_enabled; + std::optional<CORE_ADDR> ssp + = gdbarch_get_shadow_stack_pointer (gdbarch, regs, + shadow_stack_enabled); + if (shadow_stack_enabled) + { + gdb_assert (ssp.has_value ()); + write_memory_unsigned_integer (*ssp, retaddr_len, byte_order, + retaddr); + displaced_debug_printf ("relocated shadow stack return addr at %s " + "to %s", paddress (gdbarch, *ssp), + paddress (gdbarch, retaddr)); + } } } @@ -3879,9 +3894,9 @@ int i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) { return (*s == '$' /* Literal number. */ - || (isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement. */ + || (c_isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement. */ || (*s == '(' && s[1] == '%') /* Register indirection. */ - || (*s == '%' && isalpha (s[1]))); /* Register access. */ + || (*s == '%' && c_isalpha (s[1]))); /* Register access. */ } /* Helper function for i386_stap_parse_special_token. @@ -3898,7 +3913,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch, { const char *s = p->arg; - if (isdigit (*s) || *s == '-' || *s == '+') + if (c_isdigit (*s) || *s == '-' || *s == '+') { bool got_minus[3]; int i; @@ -3916,7 +3931,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch, got_minus[0] = true; } - if (!isdigit ((unsigned char) *s)) + if (!c_isdigit (*s)) return {}; displacements[0] = strtol (s, &endp, 10); @@ -3937,7 +3952,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch, got_minus[1] = true; } - if (!isdigit ((unsigned char) *s)) + if (!c_isdigit (*s)) return {}; displacements[1] = strtol (s, &endp, 10); @@ -3958,7 +3973,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch, got_minus[2] = true; } - if (!isdigit ((unsigned char) *s)) + if (!c_isdigit (*s)) return {}; displacements[2] = strtol (s, &endp, 10); @@ -3970,7 +3985,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch, s += 2; start = s; - while (isalnum (*s)) + while (c_isalnum (*s)) ++s; if (*s++ != ')') @@ -4031,7 +4046,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch, { const char *s = p->arg; - if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+') + if (c_isdigit (*s) || *s == '(' || *s == '-' || *s == '+') { bool offset_minus = false; long offset = 0; @@ -4049,10 +4064,10 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch, offset_minus = true; } - if (offset_minus && !isdigit (*s)) + if (offset_minus && !c_isdigit (*s)) return {}; - if (isdigit (*s)) + if (c_isdigit (*s)) { char *endp; @@ -4066,7 +4081,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch, s += 2; start = s; - while (isalnum (*s)) + while (c_isalnum (*s)) ++s; if (*s != ',' || s[1] != '%') @@ -4082,7 +4097,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch, s += 2; start = s; - while (isalnum (*s)) + while (c_isalnum (*s)) ++s; len_index = s - start; @@ -8580,7 +8595,8 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep, const struct tdesc_feature *feature_core; const struct tdesc_feature *feature_sse, *feature_avx, *feature_avx512, - *feature_pkeys, *feature_segments; + *feature_pkeys, *feature_segments, + *feature_pl3_ssp; int i, num_regs, valid_p; if (! tdesc_has_registers (tdesc)) @@ -8606,6 +8622,9 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep, /* Try PKEYS */ feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys"); + /* Try Shadow Stack. */ + feature_pl3_ssp = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pl3_ssp"); + valid_p = 1; /* The XCR0 bits. */ @@ -8721,6 +8740,15 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep, tdep->pkeys_register_names[i]); } + if (feature_pl3_ssp != nullptr) + { + if (tdep->ssp_regnum < 0) + tdep->ssp_regnum = I386_PL3_SSP_REGNUM; + + valid_p &= tdesc_numbered_register (feature_pl3_ssp, tdesc_data, + tdep->ssp_regnum, "pl3_ssp"); + } + return valid_p; } @@ -9097,23 +9125,25 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) -/* Return the target description for a specified XSAVE feature mask. */ +/* See i386-tdep.h. */ const struct target_desc * -i386_target_description (uint64_t xcr0, bool segments) +i386_target_description (uint64_t xstate_bv, bool segments) { static target_desc *i386_tdescs \ - [2/*SSE*/][2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {}; + [2/*SSE*/][2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*CET_U*/] \ + [2/*segments*/] = {}; target_desc **tdesc; - tdesc = &i386_tdescs[(xcr0 & X86_XSTATE_SSE) ? 1 : 0] - [(xcr0 & X86_XSTATE_AVX) ? 1 : 0] - [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] - [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0] + tdesc = &i386_tdescs[(xstate_bv & X86_XSTATE_SSE) ? 1 : 0] + [(xstate_bv & X86_XSTATE_AVX) ? 1 : 0] + [(xstate_bv & X86_XSTATE_AVX512) ? 1 : 0] + [(xstate_bv & X86_XSTATE_PKRU) ? 1 : 0] + [(xstate_bv & X86_XSTATE_CET_U) ? 1 : 0] [segments ? 1 : 0]; if (*tdesc == NULL) - *tdesc = i386_create_target_description (xcr0, false, segments); + *tdesc = i386_create_target_description (xstate_bv, false, segments); return *tdesc; } |