Author: avg
Date: Mon Nov 11 19:06:04 2019
New Revision: 354627
URL: https://svnweb.freebsd.org/changeset/base/354627

Log:
  db_nextframe/i386: reduce the number of special frame types
  
  This change removes TRAP_INTERRUPT and TRAP_TIMERINT frame types.
  
  Their names are a bit confusing: trap + interrupt, what is that?
  The TRAP_TIMERINT name is too specific -- can it only be used for timer
  "trap-interrupts"?  What is so special about them?
  
  My understanding of the code is that INTERRUPT, TRAP_INTERRUPT and
  TRAP_TIMERINT differ only in how an offset from callee's frame pointer to a
  trap frame on the stack is calculated.  And that depends on a number of
  arguments that a special handler passes to a callee (a function with a
  normal C calling convention).
  
  So, this change makes that logic explicit and collapses all interrupt frame
  types into the INTERRUPT type.
  
  Reviewed by:  markj
  Discussed with:       kib, jhb
  MFC after:    3 weeks
  Differential Revision: https://reviews.freebsd.org/D22303

Modified:
  head/sys/i386/i386/db_trace.c

Modified: head/sys/i386/i386/db_trace.c
==============================================================================
--- head/sys/i386/i386/db_trace.c       Mon Nov 11 17:45:06 2019        
(r354626)
+++ head/sys/i386/i386/db_trace.c       Mon Nov 11 19:06:04 2019        
(r354627)
@@ -191,8 +191,6 @@ db_ss(struct db_variable *vp, db_expr_t *valuep, int o
 #define        INTERRUPT       2
 #define        SYSCALL         3
 #define        DOUBLE_FAULT    4
-#define        TRAP_INTERRUPT  5
-#define        TRAP_TIMERINT   6
 
 static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread *);
 static int db_numargs(struct i386_frame *);
@@ -299,6 +297,7 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
 {
        struct trapframe *tf;
        int frame_type;
+       int narg;
        int eip, esp, ebp;
        db_expr_t offset;
        c_db_sym_t sym;
@@ -317,6 +316,15 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
         * actually made the call.
         */
        frame_type = NORMAL;
+
+       /*
+        * This is the number of arguments that a syscall / trap / interrupt
+        * service routine passes to its callee.  This number is used only for
+        * special frame types.  In most cases there is one argument: the trap
+        * frame address.
+        */
+       narg = 1;
+
        if (eip >= PMAP_TRM_MIN_ADDRESS) {
                sym = db_search_symbol(eip - 1 - setidt_disp, DB_STGY_ANY,
                    &offset);
@@ -329,20 +337,24 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
                    strcmp(name, "fork_trampoline") == 0)
                        frame_type = TRAP;
                else if (strncmp(name, "Xatpic_intr", 11) == 0 ||
-                   strncmp(name, "Xapic_isr", 9) == 0)
+                   strncmp(name, "Xapic_isr", 9) == 0) {
+                       /* Additional argument: vector number. */
+                       narg = 2;
                        frame_type = INTERRUPT;
-               else if (strcmp(name, "Xlcall_syscall") == 0 ||
+               } else if (strcmp(name, "Xlcall_syscall") == 0 ||
                    strcmp(name, "Xint0x80_syscall") == 0)
                        frame_type = SYSCALL;
                else if (strcmp(name, "dblfault_handler") == 0)
                        frame_type = DOUBLE_FAULT;
-               /* XXX: These are interrupts with trap frames. */
                else if (strcmp(name, "Xtimerint") == 0)
-                       frame_type = TRAP_TIMERINT;
+                       frame_type = INTERRUPT;
                else if (strcmp(name, "Xcpustop") == 0 ||
                    strcmp(name, "Xrendezvous") == 0 ||
-                   strcmp(name, "Xipi_intr_bitmap_handler") == 0)
-                       frame_type = TRAP_INTERRUPT;
+                   strcmp(name, "Xipi_intr_bitmap_handler") == 0) {
+                       /* No arguments. */
+                       narg = 0;
+                       frame_type = INTERRUPT;
+               }
        }
 
        /*
@@ -375,14 +387,11 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
 
        /*
         * Point to base of trapframe which is just above the
-        * current frame.
+        * current frame.  Note that struct i386_frame already accounts for one
+        * argument.
         */
-       if (frame_type == INTERRUPT)
-               tf = (struct trapframe *)((int)*fp + 16);
-       else if (frame_type == TRAP_INTERRUPT)
-               tf = (struct trapframe *)((int)*fp + 8);
-       else
-               tf = (struct trapframe *)((int)*fp + 12);
+       tf = (struct trapframe *)((char *)*fp + sizeof(struct i386_frame) +
+           4 * (narg - 1));
 
        esp = get_esp(tf);
        eip = tf->tf_eip;
@@ -395,8 +404,6 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
                db_printf("--- syscall");
                decode_syscall(tf->tf_eax, td);
                break;
-       case TRAP_TIMERINT:
-       case TRAP_INTERRUPT:
        case INTERRUPT:
                db_printf("--- interrupt");
                break;
@@ -407,8 +414,6 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
 
        switch (frame_type) {
        case TRAP:
-       case TRAP_TIMERINT:
-       case TRAP_INTERRUPT:
        case INTERRUPT:
                if ((tf->tf_eflags & PSL_VM) != 0 ||
                    (tf->tf_cs & SEL_RPL_MASK) != 0)
@@ -418,7 +423,7 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, st
                ebp = 0;
                break;
        }
-       
+
        *ip = (db_addr_t) eip;
        *fp = (struct i386_frame *) ebp;
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to