Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Sep 2016 16:30:30 +0000 (UTC)
From:      Bruce Evans <bde@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r306311 - in head: share/man/man4 sys/ddb sys/i386/i386 sys/i386/include
Message-ID:  <201609251630.u8PGUUwU001468@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bde
Date: Sun Sep 25 16:30:29 2016
New Revision: 306311
URL: https://svnweb.freebsd.org/changeset/base/306311

Log:
  Determine the operand/address size of %cs in a new function
  db_segsize().
  
  Use db_segsize() to set the default operand/address size for
  disassembling.  Allow overriding this with the "alternate" display
  format /I.  The API of db_disasm() should be debooleanized to pass a
  more general request (amd64 needs overrides to sizes of 16, 32, and
  64, but this commit doesn't implement anything for amd64 since much
  larger changes are needed to restore the amd64 disassmbler's support
  for non-default sizes).
  
  Fix db_print_loc_and_inst() to ask for the normal format and not the
  alternate in normal operation.
  
  This is most useful for vm86 mode, but also works for 16-bit protected
  mode.
  
  Use db_segsize() to avoid trying to print a garbage stack trace if %cs
  is 16 bits.  Print something like the stack trace termination message
  for a trap boundary instead.
  
  Document that the alternate format is now useful on i386.

Modified:
  head/share/man/man4/ddb.4
  head/sys/ddb/db_examine.c
  head/sys/i386/i386/db_disasm.c
  head/sys/i386/i386/db_interface.c
  head/sys/i386/i386/db_trace.c
  head/sys/i386/include/db_machdep.h

Modified: head/share/man/man4/ddb.4
==============================================================================
--- head/share/man/man4/ddb.4	Sun Sep 25 14:56:24 2016	(r306310)
+++ head/share/man/man4/ddb.4	Sun Sep 25 16:30:29 2016	(r306311)
@@ -264,7 +264,9 @@ The location is also displayed in hex at
 display as an instruction
 .It Cm I
 display as an instruction with possible alternate formats depending on the
-machine, but none of the supported architectures have an alternate format
+machine.
+On i386, this selects the alternate format for the instruction decoding
+(16 bits in a 32-bit code segment and vice versa).
 .It Cm S
 display a symbol name for the pointer stored at the address
 .El

Modified: head/sys/ddb/db_examine.c
==============================================================================
--- head/sys/ddb/db_examine.c	Sun Sep 25 14:56:24 2016	(r306310)
+++ head/sys/ddb/db_examine.c	Sun Sep 25 16:30:29 2016	(r306311)
@@ -241,7 +241,7 @@ db_print_loc_and_inst(db_addr_t loc)
 	db_printsym(loc, DB_STGY_PROC);
 	if (db_search_symbol(loc, DB_STGY_PROC, &off) != C_DB_SYM_NULL) {
 		db_printf(":\t");
-		(void)db_disasm(loc, true);
+		(void)db_disasm(loc, false);
 	}
 }
 

Modified: head/sys/i386/i386/db_disasm.c
==============================================================================
--- head/sys/i386/i386/db_disasm.c	Sun Sep 25 14:56:24 2016	(r306310)
+++ head/sys/i386/i386/db_disasm.c	Sun Sep 25 16:30:29 2016	(r306311)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
  * Instruction disassembler.
  */
 #include <sys/param.h>
+#include <sys/kdb.h>
 
 #include <ddb/ddb.h>
 #include <ddb/db_access.h>
@@ -1168,9 +1169,17 @@ db_disasm(db_addr_t loc, bool altfmt)
 	int	len;
 	struct i_addr	address;
 
+	if (db_segsize(kdb_frame) == 16)
+	   altfmt = !altfmt;
 	get_value_inc(inst, loc, 1, FALSE);
-	short_addr = FALSE;
-	size = LONG;
+	if (altfmt) {
+	    short_addr = TRUE;
+	    size = WORD;
+	}
+	else {
+	    short_addr = FALSE;
+	    size = LONG;
+	}
 	seg = NULL;
 
 	/*

Modified: head/sys/i386/i386/db_interface.c
==============================================================================
--- head/sys/i386/i386/db_interface.c	Sun Sep 25 14:56:24 2016	(r306310)
+++ head/sys/i386/i386/db_interface.c	Sun Sep 25 16:30:29 2016	(r306311)
@@ -135,6 +135,30 @@ db_write_bytes(vm_offset_t addr, size_t 
 	return (ret);
 }
 
+int
+db_segsize(struct trapframe *tfp)
+{
+	struct proc_ldt *plp;
+	struct segment_descriptor *sdp;
+	int sel;
+
+	if (tfp == NULL)
+	    return (32);
+	if (tfp->tf_eflags & PSL_VM)
+	    return (16);
+	sel = tfp->tf_cs & 0xffff;
+	if (sel == GSEL(GCODE_SEL, SEL_KPL))
+	    return (32);
+	/* Rare cases follow.  User mode cases are currently unreachable. */
+	if (ISLDT(sel)) {
+	    plp = curthread->td_proc->p_md.md_ldt;
+	    sdp = (plp != NULL) ? &plp->ldt_sd : &ldt[0].sd;
+	} else {
+	    sdp = &gdt[PCPU_GET(cpuid) * NGDT].sd;
+	}
+	return (sdp[IDXSEL(sel)].sd_def32 == 0 ? 16 : 32);
+}
+
 void
 db_show_mdpcpu(struct pcpu *pc)
 {

Modified: head/sys/i386/i386/db_trace.c
==============================================================================
--- head/sys/i386/i386/db_trace.c	Sun Sep 25 14:56:24 2016	(r306310)
+++ head/sys/i386/i386/db_trace.c	Sun Sep 25 16:30:29 2016	(r306311)
@@ -421,6 +421,17 @@ db_backtrace(struct thread *td, struct t
 	int instr, narg;
 	boolean_t first;
 
+	if (db_segsize(tf) == 16) {
+		db_printf(
+"--- 16-bit%s, cs:eip = %#x:%#x, ss:esp = %#x:%#x, ebp = %#x, tf = %p ---\n",
+		    (tf->tf_eflags & PSL_VM) ? " (vm86)" : "",
+		    tf->tf_cs, tf->tf_eip,
+		    TF_HAS_STACKREGS(tf) ? tf->tf_ss : rss(),
+		    TF_HAS_STACKREGS(tf) ? tf->tf_esp : (intptr_t)&tf->tf_esp,
+		    tf->tf_ebp, tf);
+		return (0);
+	}
+
 	/*
 	 * If an indirect call via an invalid pointer caused a trap,
 	 * %pc contains the invalid address while the return address

Modified: head/sys/i386/include/db_machdep.h
==============================================================================
--- head/sys/i386/include/db_machdep.h	Sun Sep 25 14:56:24 2016	(r306310)
+++ head/sys/i386/include/db_machdep.h	Sun Sep 25 16:30:29 2016	(r306311)
@@ -98,4 +98,6 @@ do {						\
 #define	DB_SMALL_VALUE_MAX	0x7fffffff
 #define	DB_SMALL_VALUE_MIN	(-0x400001)
 
+int	db_segsize(struct trapframe *tfp);
+
 #endif /* !_MACHINE_DB_MACHDEP_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609251630.u8PGUUwU001468>