191
192 mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n",
193 kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff),
194 (kregs[KREG_GS] & 0xffff));
195 mdb_printf(" %%err = 0x%x\n", kregs[KREG_ERR]);
196 }
197
198 int
199 mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
200 mdb_tgt_stack_f *func, void *arg)
201 {
202 mdb_tgt_gregset_t gregs;
203 kreg_t *kregs = &gregs.kregs[0];
204 int got_pc = (gsp->kregs[KREG_RIP] != 0);
205 uint_t argc, reg_argc;
206 long fr_argv[32];
207 int start_index; /* index to save_instr where to start comparison */
208 int err;
209 int i;
210
211 struct {
212 uintptr_t fr_savfp;
213 uintptr_t fr_savpc;
214 } fr;
215
216 uintptr_t fp = gsp->kregs[KREG_RBP];
217 uintptr_t pc = gsp->kregs[KREG_RIP];
218 uintptr_t lastfp = 0;
219
220 ssize_t size;
221 ssize_t insnsize;
222 uint8_t ins[SAVEARGS_INSN_SEQ_LEN];
223
224 GElf_Sym s;
225 mdb_syminfo_t sip;
226 mdb_ctf_funcinfo_t mfp;
227 int xpv_panic = 0;
228 #ifndef _KMDB
229 int xp;
230
231 if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0))
232 xpv_panic = 1;
233 #endif
234
235 bcopy(gsp, &gregs, sizeof (gregs));
236
237 while (fp != 0) {
238 int args_style = 0;
239
240 /*
241 * Ensure progress (increasing fp), and prevent
242 * endless loop with the same FP.
243 */
244 if (fp <= lastfp) {
245 err = EMDB_STKFRAME;
246 goto badfp;
247 }
248 if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) {
249 err = EMDB_NOMAP;
250 goto badfp;
251 }
252
253 if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY,
254 NULL, 0, &s, &sip) == 0) &&
255 (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) {
256 int return_type = mdb_ctf_type_kind(mfp.mtf_return);
257 mdb_ctf_id_t args_types[5];
258
259 argc = mfp.mtf_argc;
260
261 /*
262 * If the function returns a structure or union
263 * greater than 16 bytes in size %rdi contains the
264 * address in which to store the return value rather
265 * than for an argument.
266 */
267 if ((return_type == CTF_K_STRUCT ||
268 return_type == CTF_K_UNION) &&
269 mdb_ctf_type_size(mfp.mtf_return) > 16)
270 start_index = 1;
271 else
272 start_index = 0;
|
191
192 mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n",
193 kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff),
194 (kregs[KREG_GS] & 0xffff));
195 mdb_printf(" %%err = 0x%x\n", kregs[KREG_ERR]);
196 }
197
198 int
199 mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
200 mdb_tgt_stack_f *func, void *arg)
201 {
202 mdb_tgt_gregset_t gregs;
203 kreg_t *kregs = &gregs.kregs[0];
204 int got_pc = (gsp->kregs[KREG_RIP] != 0);
205 uint_t argc, reg_argc;
206 long fr_argv[32];
207 int start_index; /* index to save_instr where to start comparison */
208 int err;
209 int i;
210
211 struct fr {
212 uintptr_t fr_savfp;
213 uintptr_t fr_savpc;
214 } fr;
215
216 uintptr_t fp = gsp->kregs[KREG_RBP];
217 uintptr_t pc = gsp->kregs[KREG_RIP];
218 uintptr_t lastfp = 0;
219
220 ssize_t size;
221 ssize_t insnsize;
222 uint8_t ins[SAVEARGS_INSN_SEQ_LEN];
223
224 GElf_Sym s;
225 mdb_syminfo_t sip;
226 mdb_ctf_funcinfo_t mfp;
227 int xpv_panic = 0;
228 int advance_tortoise = 1;
229 uintptr_t tortoise_fp = 0;
230 #ifndef _KMDB
231 int xp;
232
233 if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0))
234 xpv_panic = 1;
235 #endif
236
237 bcopy(gsp, &gregs, sizeof (gregs));
238
239 while (fp != 0) {
240 int args_style = 0;
241
242 if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) {
243 err = EMDB_NOMAP;
244 goto badfp;
245 }
246
247 if (tortoise_fp == 0) {
248 tortoise_fp = fp;
249 } else {
250 if (advance_tortoise != 0) {
251 struct fr tfr;
252
253 if (mdb_tgt_vread(t, &tfr, sizeof (tfr),
254 tortoise_fp) != sizeof (tfr)) {
255 err = EMDB_NOMAP;
256 goto badfp;
257 }
258
259 tortoise_fp = tfr.fr_savfp;
260 }
261
262 if (fp == tortoise_fp) {
263 err = EMDB_STKFRAME;
264 goto badfp;
265 }
266 }
267
268 advance_tortoise = !advance_tortoise;
269
270 if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY,
271 NULL, 0, &s, &sip) == 0) &&
272 (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) {
273 int return_type = mdb_ctf_type_kind(mfp.mtf_return);
274 mdb_ctf_id_t args_types[5];
275
276 argc = mfp.mtf_argc;
277
278 /*
279 * If the function returns a structure or union
280 * greater than 16 bytes in size %rdi contains the
281 * address in which to store the return value rather
282 * than for an argument.
283 */
284 if ((return_type == CTF_K_STRUCT ||
285 return_type == CTF_K_UNION) &&
286 mdb_ctf_type_size(mfp.mtf_return) > 16)
287 start_index = 1;
288 else
289 start_index = 0;
|