1 /* Target-dependent code for X86-based targets. 2 3 Copyright (C) 2018-2024 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "x86-tdep.h" 21 #include "symtab.h" 22 23 24 /* Check whether NAME is included in NAMES[LO] (inclusive) to NAMES[HI] 25 (exclusive). */ 26 27 static bool 28 x86_is_thunk_register_name (const char *name, const char * const *names, 29 int lo, int hi) 30 { 31 int reg; 32 for (reg = lo; reg < hi; ++reg) 33 if (strcmp (name, names[reg]) == 0) 34 return true; 35 36 return false; 37 } 38 39 /* See x86-tdep.h. */ 40 41 bool 42 x86_in_indirect_branch_thunk (CORE_ADDR pc, const char * const *register_names, 43 int lo, int hi) 44 { 45 struct bound_minimal_symbol bmfun = lookup_minimal_symbol_by_pc (pc); 46 if (bmfun.minsym == nullptr) 47 return false; 48 49 const char *name = bmfun.minsym->linkage_name (); 50 if (name == nullptr) 51 return false; 52 53 /* Check the indirect return thunk first. */ 54 if (strcmp (name, "__x86_return_thunk") == 0) 55 return true; 56 57 /* Then check a family of indirect call/jump thunks. */ 58 static const char thunk[] = "__x86_indirect_thunk"; 59 static const size_t length = sizeof (thunk) - 1; 60 if (strncmp (name, thunk, length) != 0) 61 return false; 62 63 /* If that's the complete name, we're in the memory thunk. */ 64 name += length; 65 if (*name == '\0') 66 return true; 67 68 /* Check for suffixes. */ 69 if (*name++ != '_') 70 return false; 71 72 if (x86_is_thunk_register_name (name, register_names, lo, hi)) 73 return true; 74 75 return false; 76 } 77