void IOOperation::Dump() const { kprintf("io_operation at %p\n", this); kprintf(" parent: %p\n", fParent); kprintf(" status: %s\n", strerror(fStatus)); kprintf(" dma buffer: %p\n", fDMABuffer); kprintf(" offset: %-8Ld (original: %Ld)\n", fOffset, fOriginalOffset); kprintf(" length: %-8lu (original: %lu)\n", fLength, fOriginalLength); kprintf(" transferred: %lu\n", fTransferredBytes); kprintf(" block size: %lu\n", fBlockSize); kprintf(" saved vec index: %u\n", fSavedVecIndex); kprintf(" saved vec length: %u\n", fSavedVecLength); kprintf(" r/w: %s\n", IsWrite() ? "write" : "read"); kprintf(" phase: %s\n", fPhase == PHASE_READ_BEGIN ? "read begin" : fPhase == PHASE_READ_END ? "read end" : fPhase == PHASE_DO_ALL ? "do all" : "unknown"); kprintf(" partial begin: %s\n", fPartialBegin ? "yes" : "no"); kprintf(" partial end: %s\n", fPartialEnd ? "yes" : "no"); kprintf(" bounce buffer: %s\n", fUsesBounceBuffer ? "yes" : "no"); set_debug_variable("_parent", (addr_t)fParent); set_debug_variable("_buffer", (addr_t)fDMABuffer); }
static void _dump_port_info(struct port_entry* port) { kprintf("PORT: %p\n", port); kprintf(" id: %ld\n", port->id); kprintf(" name: \"%s\"\n", port->lock.name); kprintf(" owner: %ld\n", port->owner); kprintf(" capacity: %ld\n", port->capacity); kprintf(" read_count: %ld\n", port->read_count); kprintf(" write_count: %ld\n", port->write_count); kprintf(" total count: %ld\n", port->total_count); if (!port->messages.IsEmpty()) { kprintf("messages:\n"); MessageList::Iterator iterator = port->messages.GetIterator(); while (port_message* message = iterator.Next()) { kprintf(" %p %08lx %ld\n", message, message->code, message->size); } } set_debug_variable("_port", (addr_t)port); set_debug_variable("_portID", port->id); set_debug_variable("_owner", port->owner); }
static void dump_sem(struct sem_entry* sem) { kprintf("SEM: %p\n", sem); kprintf("id: %ld (%#lx)\n", sem->id, sem->id); if (sem->id >= 0) { kprintf("name: '%s'\n", sem->u.used.name); kprintf("owner: %ld\n", sem->u.used.owner); kprintf("count: %ld\n", sem->u.used.count); kprintf("queue: "); if (!sem->queue.IsEmpty()) { ThreadQueue::Iterator it = sem->queue.GetIterator(); while (queued_thread* entry = it.Next()) kprintf(" %ld", entry->thread->id); kprintf("\n"); } else kprintf(" -\n"); set_debug_variable("_sem", (addr_t)sem); set_debug_variable("_semID", sem->id); set_debug_variable("_owner", sem->u.used.owner); #if DEBUG_SEM_LAST_ACQUIRER kprintf("last acquired by: %ld, count: %ld\n", sem->u.used.last_acquirer, sem->u.used.last_acquire_count); kprintf("last released by: %ld, count: %ld\n", sem->u.used.last_releaser, sem->u.used.last_release_count); if (sem->u.used.last_releaser != 0) set_debug_variable("_releaser", sem->u.used.last_releaser); else unset_debug_variable("_releaser"); #else kprintf("last acquired by: %ld\n", sem->u.used.last_acquirer); #endif if (sem->u.used.last_acquirer != 0) set_debug_variable("_acquirer", sem->u.used.last_acquirer); else unset_debug_variable("_acquirer"); } else { kprintf("next: %p\n", sem->u.unused.next); kprintf("next_id: %ld\n", sem->u.unused.next_id); } }
void IORequest::Dump() const { kprintf("io_request at %p\n", this); kprintf(" owner: %p\n", fOwner); kprintf(" parent: %p\n", fParent); kprintf(" status: %s\n", strerror(fStatus)); kprintf(" mutex: %p\n", &fLock); kprintf(" IOBuffer: %p\n", fBuffer); kprintf(" offset: %Ld\n", fOffset); kprintf(" length: %lu\n", fLength); kprintf(" transfer size: %lu\n", fTransferSize); kprintf(" relative offset: %lu\n", fRelativeParentOffset); kprintf(" pending children: %ld\n", fPendingChildren); kprintf(" flags: %#lx\n", fFlags); kprintf(" team: %ld\n", fTeam); kprintf(" thread: %ld\n", fThread); kprintf(" r/w: %s\n", fIsWrite ? "write" : "read"); kprintf(" partial transfer: %s\n", fPartialTransfer ? "yes" : "no"); kprintf(" finished cvar: %p\n", &fFinishedCondition); kprintf(" iteration:\n"); kprintf(" vec index: %lu\n", fVecIndex); kprintf(" vec offset: %lu\n", fVecOffset); kprintf(" remaining bytes: %lu\n", fRemainingBytes); kprintf(" callbacks:\n"); kprintf(" finished %p, cookie %p\n", fFinishedCallback, fFinishedCookie); kprintf(" iteration %p, cookie %p\n", fIterationCallback, fIterationCookie); kprintf(" children:\n"); IORequestChunkList::ConstIterator iterator = fChildren.GetIterator(); while (iterator.HasNext()) { kprintf(" %p\n", iterator.Next()); } set_debug_variable("_parent", (addr_t)fParent); set_debug_variable("_mutex", (addr_t)&fLock); set_debug_variable("_buffer", (addr_t)fBuffer); set_debug_variable("_cvar", (addr_t)&fFinishedCondition); }
static int cmd_expr(int argc, char **argv) { if (argc != 2) { print_debugger_command_usage(argv[0]); return 0; } uint64 result; if (evaluate_debug_expression(argv[1], &result, false)) { kprintf("%" B_PRIu64 " (0x%" B_PRIx64 ")\n", result, result); set_debug_variable("_", result); } return 0; }
static void exit_debugger(void) { if (sUseUSBKeyboard) { // make sure a possibly pending transfer is canceled set_debug_variable("_usbPipe", (uint64)sUSBPipe); if (sUseUHCI) evaluate_debug_command("uhci_process_transfer cancel"); if (sUseOHCI) evaluate_debug_command("ohci_process_transfer cancel"); if (sUseEHCI) evaluate_debug_command("ehci_process_transfer cancel"); if (sUseXHCI) evaluate_debug_command("xhci_process_transfer cancel"); sUseUSBKeyboard = false; } }
static int debug_get_pipe_for_id(int argc, char **argv) { if (gUSBStack == NULL) return 1; if (!is_debug_variable_defined("_usbPipeID")) return 2; uint64 id = get_debug_variable("_usbPipeID", 0); Object *object = gUSBStack->GetObjectNoLock((usb_id)id); if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return 3; // check if we support debug transfers for this pipe (only on UHCI for now) if (object->GetBusManager()->TypeName()[0] != 'u') return 4; set_debug_variable("_usbPipe", (uint64)object); return 0; }
uint64 ExpressionParser::_ParseExpression(bool expectAssignment) { const Token& token = fTokenizer.NextToken(); int32 position = token.position; if (token.type == TOKEN_IDENTIFIER) { char variable[MAX_DEBUG_VARIABLE_NAME_LEN]; strlcpy(variable, token.string, sizeof(variable)); int32 assignmentType = fTokenizer.NextToken().type; if (assignmentType & TOKEN_ASSIGN_FLAG) { // an assignment uint64 rhs = _ParseExpression(); // handle the standard assignment separately -- the other kinds // need the variable to be defined if (assignmentType == TOKEN_ASSIGN) { if (!set_debug_variable(variable, rhs)) { snprintf(sTempBuffer, sizeof(sTempBuffer), "failed to set value for variable \"%s\"", variable); parse_exception(sTempBuffer, position); } return rhs; } // variable must be defined if (!is_debug_variable_defined(variable)) { snprintf(sTempBuffer, sizeof(sTempBuffer), "variable \"%s\" not defined in modifying assignment", variable); parse_exception(sTempBuffer, position); } uint64 variableValue = get_debug_variable(variable, 0); // check for division by zero for the respective assignment types if ((assignmentType == TOKEN_SLASH_ASSIGN || assignmentType == TOKEN_MODULO_ASSIGN) && rhs == 0) { parse_exception("division by zero", position); } // compute the new variable value switch (assignmentType) { case TOKEN_PLUS_ASSIGN: variableValue += rhs; break; case TOKEN_MINUS_ASSIGN: variableValue -= rhs; break; case TOKEN_STAR_ASSIGN: variableValue *= rhs; break; case TOKEN_SLASH_ASSIGN: variableValue /= rhs; break; case TOKEN_MODULO_ASSIGN: variableValue %= rhs; break; default: parse_exception("internal error: unknown assignment token", position); break; } set_debug_variable(variable, variableValue); return variableValue; } } else if (token.type == TOKEN_STAR) { void* address; uint32 size; uint64 value = _ParseDereference(&address, &size); int32 assignmentType = fTokenizer.NextToken().type; if (assignmentType & TOKEN_ASSIGN_FLAG) { // an assignment uint64 rhs = _ParseExpression(); // check for division by zero for the respective assignment types if ((assignmentType == TOKEN_SLASH_ASSIGN || assignmentType == TOKEN_MODULO_ASSIGN) && rhs == 0) { parse_exception("division by zero", position); } // compute the new value switch (assignmentType) { case TOKEN_ASSIGN: value = rhs; break; case TOKEN_PLUS_ASSIGN: value += rhs; break; case TOKEN_MINUS_ASSIGN: value -= rhs; break; case TOKEN_STAR_ASSIGN: value *= rhs; break; case TOKEN_SLASH_ASSIGN: value /= rhs; break; case TOKEN_MODULO_ASSIGN: value %= rhs; break; default: parse_exception("internal error: unknown assignment token", position); break; } // convert the value for writing to the address uint64 buffer = 0; switch (size) { case 1: *(uint8*)&buffer = value; break; case 2: *(uint16*)&buffer = value; break; case 4: *(uint32*)&buffer = value; break; case 8: value = buffer; break; } if (debug_memcpy(B_CURRENT_TEAM, address, &buffer, size) != B_OK) { snprintf(sTempBuffer, sizeof(sTempBuffer), "failed to write to address %p", address); parse_exception(sTempBuffer, position); } return value; } } if (expectAssignment) { parse_exception("expected assignment", fTokenizer.CurrentToken().position); } // no assignment -- reset to the identifier position and parse a sum fTokenizer.SetPosition(position); return _ParseSum(false, 0); }
static int debugger_getchar(void) { if (!sUseUSBKeyboard) return -1; if (sBufferedCharCount == 0) { set_debug_variable("_usbPipe", (uint64)sUSBPipe); set_debug_variable("_usbTransferData", (uint64)sUSBTransferData); set_debug_variable("_usbTransferLength", (uint64)sUSBTransferLength); if ((!sUseUHCI || evaluate_debug_command("uhci_process_transfer") != 0) && (!sUseOHCI || evaluate_debug_command("ohci_process_transfer") != 0) && (!sUseEHCI || evaluate_debug_command("ehci_process_transfer") != 0) && (!sUseXHCI || evaluate_debug_command("xhci_process_transfer") != 0)) { return -1; } bool phantomState = true; for (size_t i = 2; i < sUSBTransferLength; i++) { if (sUSBTransferData[i] != 0x01) { phantomState = false; break; } } if (phantomState) return -1; uint8 modifiers = 0; for (uint32 i = 0; i < 8; i++) { if (sUSBTransferData[0] & (1 << i)) modifiers |= sModifierTable[i]; } uint8 *current = sUSBTransferData; uint8 *compare = sLastTransferData; for (uint32 i = 2; i < sUSBTransferLength; i++) { if (current[i] == 0x00 || current[i] == 0x01) continue; bool found = false; for (uint32 j = 2; j < sUSBTransferLength; j++) { if (compare[j] == current[i]) { found = true; break; } } if (found) continue; if (current[i] >= sKeyTableSize) continue; int result = -1; uint8 key = sKeyTable[current[i]]; if (key & 0x80) { write_key(27); write_key('['); key &= ~0x80; write_key(key); if (key == '5' || key == '6' || key == '3') write_key('~'); continue; } else if (modifiers & MODIFIER_CONTROL) { char c = kShiftedKeymap[key]; if (c >= 'A' && c <= 'Z') result = 0x1f & c; } else if (modifiers & MODIFIER_ALT) result = kAltedKeymap[key]; else if (modifiers & MODIFIER_SHIFT) result = kShiftedKeymap[key]; else result = kUnshiftedKeymap[key]; if (result < 0) continue; write_key(result); } for (uint32 i = 0; i < sUSBTransferLength; i++) sLastTransferData[i] = sUSBTransferData[i]; } if (sBufferedCharCount == 0) return -1; int result = sBufferedChars[sBufferReadIndex++]; sBufferReadIndex %= sBufferSize; sBufferedCharCount--; return result; }