Building An OS-Aware Debugger by Stewart Christie Listing One .... memset(&osCalls, 0, sizeof(osCalls)); osCalls.flag = OS_TASK_LIST | OS_TASK_INFO | OS_GET_TASK_ID | OS_LOAD_INFO | OS_QUERY | OS_COMMAND | OS_GET_ERROR_MESSAGE; osCalls.OS_Task_List = callOSTaskList; osCalls.OS_Task_Info = callOSTaskInfo; osCalls.OS_Get_Task_ID = callOSGetTaskID; osCalls.OS_Load_Info = callOSLoadInfo; osCalls.OS_Query = callOSQuery; osCalls.OS_Command = callOSCommand; osCalls.OS_Get_Error_Message = callOSGetErrorMessage; m386_setOScalls((OS_calls_t far *)&osCalls); ..... Listing Two /* Function Pointers */ #pragma noalign (s_calls) typedef struct s_calls { OS_int flag; /* flag for available functions */ #define OS_TASK_LIST (1 << 0) #define OS_TASK_INFO (1 << 1) #define OS_SET_TASK (1 << 2) #define OS_GET_TASK (1 << 3) #define OS_GET_TSS (1 << 4) #define OS_SET_TSS (1 << 5) #define OS_GET_TASK_ID (1 << 6) #define OS_COMMAND (1 << 7) #define OS_GET_OUTPUT (1 << 8) #define OS_GET_ERROR_MESSAGE (1 << 9) #define OS_LOAD (1 << 10) #define OS_LOAD_INFO (1 << 11) #define OS_SET_COMPLEX_BREAKPOINT_CONDITION (1 << 12) #define OS_GET_COMPLEX_BREAKPOINT_CONDITION (1 << 13) #define OS_DELETE_COMPLEX_BREAKPOINT_CONDITION (1 << 14) #define OS_QUERY (1 << 15) #define OS_GET_FPU (1 << 16) #define OS_SET_FPU (1 << 17) #define OS_BREAK (1 << 18) /* 1 */OS_int far (*OS_Task_List)(OS_asbyte, OS_task_t far *); /* 2 */OS_int far (*OS_Task_Info)(OS_int, OS_msg_t far *); /* 3 */OS_int far (*OS_Set_Task)(OS_int, OS_int, OS_int far *); /* 4 */OS_int far (*OS_Get_Task)(OS_int far *); /* 5 */OS_int far (*OS_Get_TSS)(OS_int, OS_tss_t far *, OS_void far *); /* 6 */OS_int far (*OS_Set_TSS)(OS_int, OS_tss_t far *); /* 7 */OS_int far (*OS_Get_Task_ID)(OS_asbyte, OS_byte far *); /* 8 */OS_int far (*OS_Command)(OS_asbyte, OS_byte far *, OS_msg_t far*); /* 9 */OS_int far (*OS_Get_Output)(OS_asbyte, OS_asbyte, OS_msg_t far*); /* 0 */OS_int far (*OS_Get_Error_Message)(OS_asbyte, OS_err_t far *); /* 11 */OS_int far (*OS_Load)(OS_asbyte, OS_byte far *, OS_msg_t far *); /* 12 */OS_int far (*OS_Load_Info) (OS_asbyte, OS_asbyte, OS_byte far *,OS_load_t far *); /* 13 */OS_int far (*OS_Set_Complex_Breakpoint_Condition) (OS_asbyte, OS_byte far *); /* 14 */OS_int far (*OS_Get_Complex_Breakpoint_Condition) (OS_asbyte, OS_msg_t far *); /* 15 */OS_int far (*OS_Delete_Complex_Breakpoint_Condition)(OS_long); /* 16 */OS_int far (*OS_Query)(OS_asbyte, OS_byte far *, OS_msg_t far*); /* 17 */OS_int far (*OS_Get_FPU)(OS_int, OS_fpu_t far *); /* 18 */OS_int far (*OS_Set_FPU)(OS_int, OS_fpu_t far *); /* 19 */OS_int far (*OS_Break)(OS_int *); #define OS_CALLS_MAX 19 } OS_calls_t; Listing Three /* --------------------------------------------------------------------- * MethodName: callOSTaskList * --------------------------------------------------------------------- * Description: wrapper function for near/far pointer conversion; * OSTaskList can be found in file 'moninit.c' * --------------------------------------------------------------------- * Access: global * --------------------------------------------------------------------- * Parameter: length * ----------------------------------------- * Parameter: pTask * pointer to caller's task structure to be filled * --------------------------------------------------------------------- * Return: OS_SUCCESS, for successful result * --------------------------------------------------------------------- * Pre: none * --------------------------------------------------------------------- */ OS_int far callOSTaskList(OS_asbyte length, OS_task_t far* pTask) { struct OS_near_task task; OS_int result; task.ID = pTask->ID; task.state = pTask->state; task.length = pTask->length; task.name = (OS_byte*)pTask->name; result = (*pOSTaskList)(length, (OS_task_t*)&task); pTask->ID = task.ID; pTask->state = task.state; pTask->length = task.length; pTask->name = (OS_byte far*)task.name; return result; } Listing Four OS_int OSTaskList(OS_asbyte n, OS_task_t* pTask) { pthread_t p; ... p = GetTask(n); if (p) { static char szBuffer[20]; sprintf(szBuffer, "%08x", p); pTask->ID = (OS_int)p; pTask->state = p->state; pTask->length = 9; pTask->name = szBuffer; } else {..... } return n == GetTaskCount() - 1 ? OS_NONE : n + 1; } pthread_t GetTask(int n) { int I = 0; pthread_t p = rtl_sched[i].rtl_tasks; for (i = 0; I <= n && p != 0; i++) { // first element is 0, second is 1, etc. if (i == n) { return p; } p = p->next; } return NULL; } Listing Five OS_int OSTaskList(OS_asbyte n, OS_task_t* pTask) { struct task* p; p = GetTask(n); if (!p) { pTask->ID = p->pid; pTask->state = p->state; pTask->length = strlen(p->cmdline) + 1; pTask->name = (void*)&(p->cmdline); if (p->pid == GetAttachedProcessID()) { pTask->state = OS_DEBUG; } return n == GetTaskCount() - 1 ? OS_NONE : n + 1; } 3