/** * Helper for scmDiffCompare that takes care of trailing spaces and stuff * like that. */ static bool scmDiffCompareSlow(PSCMDIFFSTATE pState, const char *pchLeft, size_t cchLeft, SCMEOL enmEolLeft, const char *pchRight, size_t cchRight, SCMEOL enmEolRight) { if (pState->fIgnoreTrailingWhite) { while (cchLeft > 0 && RT_C_IS_SPACE(pchLeft[cchLeft - 1])) cchLeft--; while (cchRight > 0 && RT_C_IS_SPACE(pchRight[cchRight - 1])) cchRight--; } if (pState->fIgnoreLeadingWhite) { while (cchLeft > 0 && RT_C_IS_SPACE(*pchLeft)) pchLeft++, cchLeft--; while (cchRight > 0 && RT_C_IS_SPACE(*pchRight)) pchRight++, cchRight--; } if ( cchLeft != cchRight || (enmEolLeft != enmEolRight && !pState->fIgnoreEol) || memcmp(pchLeft, pchRight, cchLeft)) return false; return true; }
/** * Strips all kind of spaces from head and tail of a string. */ static char *dbgfR3Strip(char *psz) { while (*psz && RT_C_IS_SPACE(*psz)) psz++; char *psz2 = strchr(psz, '\0') - 1; while (psz2 >= psz && RT_C_IS_SPACE(*psz2)) *psz2-- = '\0'; return psz; }
/** * Strips blankspaces from both ends of the string. * * @returns Pointer to first non-blank char in the string. * @param psz The string to strip. */ RTDECL(char *) RTStrStrip(char *psz) { /* left */ while (RT_C_IS_SPACE(*psz)) psz++; /* right */ char *pszEnd = strchr(psz, '\0'); while (--pszEnd > psz && RT_C_IS_SPACE(*pszEnd)) *pszEnd = '\0'; return psz; }
/** * Strips blankspaces from the start of the string. * * @returns Pointer to first non-blank char in the string. * @param psz The string to strip. */ RTDECL(char *) RTStrStripL(const char *psz) { /* left */ while (RT_C_IS_SPACE(*psz)) psz++; return (char *)psz; }
/** * Checks if the given line is empty or full of white space. * * @returns true if white space only, false if not (or if non-existant). * @param pStream The stream. Must be in read mode. * @param iLine The line in question. */ bool ScmStreamIsWhiteLine(PSCMSTREAM pStream, size_t iLine) { SCMEOL enmEol; size_t cchLine; const char *pchLine = ScmStreamGetLineByNo(pStream, iLine, &cchLine, &enmEol); if (!pchLine) return false; while (cchLine && RT_C_IS_SPACE(*pchLine)) pchLine++, cchLine--; return cchLine == 0; }
/** * Info handler, internal version. * * @param pVM Pointer to the VM. * @param pHlp Callback functions for doing output. * @param pszArgs Argument string. Optional and specific to the handler. */ static DECLCALLBACK(void) dbgfR3InfoHelp(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) { LogFlow(("dbgfR3InfoHelp: pszArgs=%s\n", pszArgs)); /* * Enter and enumerate. */ PUVM pUVM = pVM->pUVM; int rc = RTCritSectEnter(&pUVM->dbgf.s.InfoCritSect); AssertRC(rc); if (pszArgs && *pszArgs) { for (PDBGFINFO pInfo = pUVM->dbgf.s.pInfoFirst; pInfo; pInfo = pInfo->pNext) { const char *psz = strstr(pszArgs, pInfo->szName); if ( psz && ( psz == pszArgs || RT_C_IS_SPACE(psz[-1])) && ( !psz[pInfo->cchName] || RT_C_IS_SPACE(psz[pInfo->cchName]))) pHlp->pfnPrintf(pHlp, "%-16s %s\n", pInfo->szName, pInfo->pszDesc); } } else { for (PDBGFINFO pInfo = pUVM->dbgf.s.pInfoFirst; pInfo; pInfo = pInfo->pNext) pHlp->pfnPrintf(pHlp, "%-16s %s\n", pInfo->szName, pInfo->pszDesc); } /* * Leave and exit. */ rc = RTCritSectLeave(&pUVM->dbgf.s.InfoCritSect); AssertRC(rc); }
static void test3(void) { RTTestISub("> 127"); for (int ch = 128; ch < 2000000; ch++) { RTTESTI_CHECK(!RT_C_IS_CNTRL(ch)); RTTESTI_CHECK(!RT_C_IS_SPACE(ch)); RTTESTI_CHECK(!RT_C_IS_BLANK(ch)); RTTESTI_CHECK(!RT_C_IS_PRINT(ch)); RTTESTI_CHECK(!RT_C_IS_PUNCT(ch)); RTTESTI_CHECK(!RT_C_IS_GRAPH(ch)); RTTESTI_CHECK(!RT_C_IS_DIGIT(ch)); RTTESTI_CHECK(!RT_C_IS_XDIGIT(ch)); RTTESTI_CHECK(!RT_C_IS_ODIGIT(ch)); RTTESTI_CHECK(!RT_C_IS_ALPHA(ch)); RTTESTI_CHECK(!RT_C_IS_UPPER(ch)); RTTESTI_CHECK(!RT_C_IS_LOWER(ch)); } }
static void test2(void) { RTTestISub("< 0"); for (int ch = -1; ch > -2000000; ch--) { RTTESTI_CHECK(!RT_C_IS_CNTRL(ch)); RTTESTI_CHECK(!RT_C_IS_SPACE(ch)); RTTESTI_CHECK(!RT_C_IS_BLANK(ch)); RTTESTI_CHECK(!RT_C_IS_PRINT(ch)); RTTESTI_CHECK(!RT_C_IS_PUNCT(ch)); RTTESTI_CHECK(!RT_C_IS_GRAPH(ch)); RTTESTI_CHECK(!RT_C_IS_DIGIT(ch)); RTTESTI_CHECK(!RT_C_IS_XDIGIT(ch)); RTTESTI_CHECK(!RT_C_IS_ODIGIT(ch)); RTTESTI_CHECK(!RT_C_IS_ALPHA(ch)); RTTESTI_CHECK(!RT_C_IS_UPPER(ch)); RTTESTI_CHECK(!RT_C_IS_LOWER(ch)); } }
/** * @copydoc DBGFOSREG::pfnQueryVersion */ static DECLCALLBACK(int) dbgDiggerLinuxQueryVersion(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion) { PDBGDIGGERLINUX pThis = (PDBGDIGGERLINUX)pvData; Assert(pThis->fValid); /* * It's all in the linux banner. */ int rc = DBGFR3MemReadString(pUVM, 0, &pThis->AddrLinuxBanner, pszVersion, cchVersion); if (RT_SUCCESS(rc)) { char *pszEnd = RTStrEnd(pszVersion, cchVersion); AssertReturn(pszEnd, VERR_BUFFER_OVERFLOW); while ( pszEnd > pszVersion && RT_C_IS_SPACE(pszEnd[-1])) pszEnd--; *pszEnd = '\0'; } else RTStrPrintf(pszVersion, cchVersion, "DBGFR3MemRead -> %Rrc", rc); return rc; }
/** * Attempts to convert an ISO date string to a time structure. * * We're a little forgiving with zero padding, unspecified parts, and leading * and trailing spaces. * * @retval pTime on success, * @retval NULL on failure. * @param pTime Where to store the time on success. * @param pszString The ISO date string to convert. */ RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString) { /* Ignore leading spaces. */ while (RT_C_IS_SPACE(*pszString)) pszString++; /* * Init non date & time parts. */ pTime->fFlags = RTTIME_FLAGS_TYPE_LOCAL; pTime->offUTC = 0; /* * The day part. */ /* Year */ int rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->i32Year); if (rc != VWRN_TRAILING_CHARS) return NULL; bool const fLeapYear = rtTimeIsLeapYear(pTime->i32Year); if (fLeapYear) pTime->fFlags |= RTTIME_FLAGS_LEAP_YEAR; if (*pszString++ != '-') return NULL; /* Month of the year. */ rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Month); if (rc != VWRN_TRAILING_CHARS) return NULL; if (pTime->u8Month == 0 || pTime->u8Month > 12) return NULL; if (*pszString++ != '-') return NULL; /* Day of month.*/ rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8MonthDay); if (rc != VWRN_TRAILING_CHARS && rc != VINF_SUCCESS) return NULL; unsigned const cDaysInMonth = fLeapYear ? g_acDaysInMonthsLeap[pTime->u8Month - 1] : g_acDaysInMonths[pTime->u8Month - 1]; if (pTime->u8MonthDay == 0 || pTime->u8MonthDay > cDaysInMonth) return NULL; /* Calculate year day. */ pTime->u16YearDay = pTime->u8MonthDay - 1 + (fLeapYear ? g_aiDayOfYearLeap[pTime->u8Month - 1] : g_aiDayOfYear[pTime->u8Month - 1]); /* * The time part. */ if (*pszString++ != 'T') return NULL; /* Hour. */ rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Hour); if (rc != VWRN_TRAILING_CHARS) return NULL; if (pTime->u8Hour > 23) return NULL; if (*pszString++ != ':') return NULL; /* Minute. */ rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Minute); if (rc != VWRN_TRAILING_CHARS) return NULL; if (pTime->u8Minute > 59) return NULL; if (*pszString++ != ':') return NULL; /* Second. */ rc = RTStrToUInt8Ex(pszString, (char **)&pszString, 10, &pTime->u8Minute); if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES) return NULL; if (pTime->u8Second > 59) return NULL; /* Nanoseconds is optional and probably non-standard. */ if (*pszString == '.') { rc = RTStrToUInt32Ex(pszString + 1, (char **)&pszString, 10, &pTime->u32Nanosecond); if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES) return NULL; if (pTime->u32Nanosecond >= 1000000000) return NULL; } else pTime->u32Nanosecond = 0; /* * Time zone. */ if (*pszString == 'Z') { pszString++; pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK; pTime->fFlags |= ~RTTIME_FLAGS_TYPE_UTC; pTime->offUTC = 0; } else if ( *pszString == '+' || *pszString == '-') { rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->offUTC); if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES) return NULL; } /* else: No time zone given, local with offUTC = 0. */ /* * The rest of the string should be blanks. */ char ch; while ((ch = *pszString++) != '\0') if (!RT_C_IS_BLANK(ch)) return NULL; return pTime; }
static int ParseUsbIds(PRTSTREAM pInStrm, const char *pszFile) { /* * State data. */ VendorRecord vendor = { 0, 0, 0, "" }; /* * Process the file line-by-line. * * The generic format is that we have top level entries (vendors) starting * in position 0 with sub entries starting after one or more, depending on * the level, tab characters. * * Specifically, the list of vendors and their products will always start * with a vendor line followed by indented products. The first character * on the vendor line is a hex digit (four in total) that makes up the * vendor ID. The product lines equally starts with a 4 digit hex ID value. * * Other lists are assumed to have first lines that doesn't start with any * lower case hex digit. */ uint32_t iLine = 0;; for (;;) { char szLine[_4K]; int rc = RTStrmGetLine(pInStrm, szLine, sizeof(szLine)); if (RT_SUCCESS(rc)) { iLine++; /* Check for vendor line. */ char chType = szLine[0]; if ( RT_C_IS_XDIGIT(chType) && RT_C_IS_SPACE(szLine[4]) && RT_C_IS_XDIGIT(szLine[1]) && RT_C_IS_XDIGIT(szLine[2]) && RT_C_IS_XDIGIT(szLine[3]) ) { if (ParseAlias(szLine, vendor.vendorID, vendor.str) == 0) g_vendors.push_back(vendor); else return RTMsgErrorExit((RTEXITCODE)ERROR_IN_PARSE_LINE, "%s(%d): Error in parsing vendor line: '%s'", pszFile, iLine, szLine); } /* Check for product line. */ else if (szLine[0] == '\t' && vendor.vendorID != 0) { ProductRecord product = { 0, vendor.vendorID, 0, "" }; if (ParseAlias(&szLine[1], product.productID, product.str) == 0) { product.key = RT_MAKE_U32(product.productID, product.vendorID); Assert(product.vendorID == vendor.vendorID); g_products.push_back(product); } else return RTMsgErrorExit((RTEXITCODE)ERROR_IN_PARSE_LINE, "Error in parsing product line: '%s'", szLine); } /* If not a blank or comment line, it is some other kind of data. So, make sure the vendor ID is cleared so we don't try process the sub-items of in some other list as products. */ else if ( chType != '#' && chType != '\0' && *RTStrStripL(szLine) != '\0') vendor.vendorID = 0; } else if (rc == VERR_EOF) return RTEXITCODE_SUCCESS; else return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmGetLine failed: %Rrc", rc); } }
RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread) { RTTHREADNATIVESTATE enmRet = RTTHREADNATIVESTATE_INVALID; PRTTHREADINT pThread = rtThreadGet(hThread); if (pThread) { enmRet = RTTHREADNATIVESTATE_UNKNOWN; char szName[512]; RTStrPrintf(szName, sizeof(szName), "/proc/self/task/%u/stat", pThread->tid); int fd = open(szName, O_RDONLY, 0); if (fd >= 0) { ssize_t cch = read(fd, szName, sizeof(szName) - 1); close(fd); if (cch > 0) { szName[cch] = '\0'; /* skip the pid, the (comm name) and stop at the status char. */ const char *psz = szName; while ( *psz && ( *psz != ')' || !RT_C_IS_SPACE(psz[1]) || !RT_C_IS_ALPHA(psz[2]) || !RT_C_IS_SPACE(psz[3]) ) ) psz++; if (*psz == ')') { switch (psz[2]) { case 'R': /* running */ enmRet = RTTHREADNATIVESTATE_RUNNING; break; case 'S': /* sleeping */ case 'D': /* disk sleeping */ enmRet = RTTHREADNATIVESTATE_BLOCKED; break; case 'T': /* stopped or tracking stop */ enmRet = RTTHREADNATIVESTATE_SUSPENDED; break; case 'Z': /* zombie */ case 'X': /* dead */ enmRet = RTTHREADNATIVESTATE_TERMINATED; break; default: AssertMsgFailed(("state=%c\n", psz[2])); enmRet = RTTHREADNATIVESTATE_UNKNOWN; break; } } else AssertMsgFailed(("stat='%s'\n", szName)); } } rtThreadRelease(pThread); } return enmRet; }
/** * Looks for a PEM-like marker. * * @returns true if found, fasle if not. * @param pbContent Start of the content to search thru. * @param cbContent The size of the content to search. * @param offStart The offset into pbContent to start searching. * @param pszLeadWord The lead word (BEGIN/END). * @param cchLeadWord The length of the lead word. * @param paMarkers Pointer to an array of markers. * @param cMarkers Number of markers in the array. * @param ppMatch Where to return the pointer to the matching * marker. Optional. * @param poffBegin Where to return the start offset of the marker. * Optional. * @param poffEnd Where to return the end offset of the marker * (trailing whitespace and newlines will be * skipped). Optional. */ static bool rtCrPemFindMarker(uint8_t const *pbContent, size_t cbContent, size_t offStart, const char *pszLeadWord, size_t cchLeadWord, PCRTCRPEMMARKER paMarkers, size_t cMarkers, PCRTCRPEMMARKER *ppMatch, size_t *poffBegin, size_t *poffEnd) { /* Remember the start of the content for the purpose of calculating offsets. */ uint8_t const * const pbStart = pbContent; /* Skip adhead by offStart */ if (offStart >= cbContent) return false; pbContent += offStart; cbContent -= offStart; /* * Search the content. */ while (cbContent > 6) { /* * Look for dashes. */ uint8_t const *pbStartSearch = pbContent; pbContent = (uint8_t const *)memchr(pbContent, '-', cbContent); if (!pbContent) break; cbContent -= pbContent - pbStartSearch; if (cbContent < 6) break; /* * There must be at least three to interest us. */ if ( pbContent[1] == '-' && pbContent[2] == '-') { unsigned cDashes = 3; while (cDashes < cbContent && pbContent[cDashes] == '-') cDashes++; if (poffBegin) *poffBegin = pbContent - pbStart; cbContent -= cDashes; pbContent += cDashes; /* * Match lead word. */ if ( cbContent > cchLeadWord && memcmp(pbContent, pszLeadWord, cchLeadWord) == 0 && RT_C_IS_BLANK(pbContent[cchLeadWord]) ) { pbContent += cchLeadWord; cbContent -= cchLeadWord; while (cbContent > 0 && RT_C_IS_BLANK(*pbContent)) { pbContent++; cbContent--; } /* * Match one of the specified markers. */ uint8_t const *pbSavedContent = pbContent; size_t const cbSavedContent = cbContent; uint32_t iMarker = 0; while (iMarker < cMarkers) { pbContent = pbSavedContent; cbContent = cbSavedContent; uint32_t cWords = paMarkers[iMarker].cWords; PCRTCRPEMMARKERWORD pWord = paMarkers[iMarker].paWords; while (cWords > 0) { uint32_t const cchWord = pWord->cchWord; if (cbContent <= cchWord) break; if (memcmp(pbContent, pWord->pszWord, cchWord)) break; pbContent += cchWord; cbContent -= cchWord; if (!cbContent || !RT_C_IS_BLANK(*pbContent)) break; do { pbContent++; cbContent--; } while (cbContent > 0 && RT_C_IS_BLANK(*pbContent)); cWords--; if (cWords == 0) { /* * If there are three or more dashes following now, we've got a hit. */ if ( cbContent > 3 && pbContent[0] == '-' && pbContent[1] == '-' && pbContent[2] == '-') { cDashes = 3; while (cDashes < cbContent && pbContent[cDashes] == '-') cDashes++; cbContent -= cDashes; pbContent += cDashes; /* * Skip spaces and newline. */ while (cbContent > 0 && RT_C_IS_SPACE(*pbContent)) pbContent++, cbContent--; if (poffEnd) *poffEnd = pbContent - pbStart; if (*ppMatch) *ppMatch = &paMarkers[iMarker]; return true; } break; } } /* for each word in marker. */ } /* for each marker. */ } } else { pbContent++; cbContent--; } } return false; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); const char * const argv0 = RTPathFilename(argv[0]); /* options */ uint64_t uAddress = 0; uint64_t uHighlightAddr = UINT64_MAX; ASMSTYLE enmStyle = kAsmStyle_Default; UNDEFOPHANDLING enmUndefOp = kUndefOp_Fail; bool fListing = true; DISCPUMODE enmCpuMode = DISCPUMODE_32BIT; RTFOFF off = 0; RTFOFF cbMax = _1G; bool fHexBytes = false; /* * Parse arguments. */ static const RTGETOPTDEF g_aOptions[] = { { "--address", 'a', RTGETOPT_REQ_UINT64 }, { "--cpumode", 'c', RTGETOPT_REQ_UINT32 }, { "--bytes", 'b', RTGETOPT_REQ_INT64 }, { "--listing", 'l', RTGETOPT_REQ_NOTHING }, { "--no-listing", 'L', RTGETOPT_REQ_NOTHING }, { "--offset", 'o', RTGETOPT_REQ_INT64 }, { "--style", 's', RTGETOPT_REQ_STRING }, { "--undef-op", 'u', RTGETOPT_REQ_STRING }, { "--hex-bytes", 'x', RTGETOPT_REQ_NOTHING }, }; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); while ( (ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION) { switch (ch) { case 'a': uAddress = ValueUnion.u64; break; case 'b': cbMax = ValueUnion.i64; break; case 'c': if (ValueUnion.u32 == 16) enmCpuMode = DISCPUMODE_16BIT; else if (ValueUnion.u32 == 32) enmCpuMode = DISCPUMODE_32BIT; else if (ValueUnion.u32 == 64) enmCpuMode = DISCPUMODE_64BIT; else { RTStrmPrintf(g_pStdErr, "%s: Invalid CPU mode value %RU32\n", argv0, ValueUnion.u32); return 1; } break; case 'h': return Usage(argv0); case 'l': fListing = true; break; case 'L': fListing = false; break; case 'o': off = ValueUnion.i64; break; case 's': if (!strcmp(ValueUnion.psz, "default")) enmStyle = kAsmStyle_Default; else if (!strcmp(ValueUnion.psz, "yasm")) enmStyle = kAsmStyle_yasm; else if (!strcmp(ValueUnion.psz, "masm")) { enmStyle = kAsmStyle_masm; RTStrmPrintf(g_pStdErr, "%s: masm style isn't implemented yet\n", argv0); return 1; } else { RTStrmPrintf(g_pStdErr, "%s: unknown assembly style: %s\n", argv0, ValueUnion.psz); return 1; } break; case 'u': if (!strcmp(ValueUnion.psz, "fail")) enmUndefOp = kUndefOp_Fail; else if (!strcmp(ValueUnion.psz, "all")) enmUndefOp = kUndefOp_All; else if (!strcmp(ValueUnion.psz, "db")) enmUndefOp = kUndefOp_DefineByte; else { RTStrmPrintf(g_pStdErr, "%s: unknown undefined opcode handling method: %s\n", argv0, ValueUnion.psz); return 1; } break; case 'x': fHexBytes = true; break; case 'V': RTPrintf("$Revision: $\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } int iArg = GetState.iNext - 1; /** @todo Not pretty, add RTGetOptInit flag for this. */ if (iArg >= argc) return Usage(argv0); int rc = VINF_SUCCESS; if (fHexBytes) { /* * Convert the remaining arguments from a hex byte string into * a buffer that we disassemble. */ size_t cb = 0; uint8_t *pb = NULL; for ( ; iArg < argc; iArg++) { char ch2; const char *psz = argv[iArg]; while (*psz) { /** @todo this stuff belongs in IPRT, same stuff as mac address reading. Could be reused for IPv6 with a different item size.*/ /* skip white space, and for the benefit of linux panics '<' and '>'. */ while (RT_C_IS_SPACE(ch2 = *psz) || ch2 == '<' || ch2 == '>' || ch2 == ',' || ch2 == ';') { if (ch2 == '<') uHighlightAddr = uAddress + cb; psz++; } if (ch2 == '0' && (psz[1] == 'x' || psz[1] == 'X')) { psz += 2; ch2 = *psz; } if (!ch2) break; /* one digit followed by a space or EOS, or two digits. */ int iNum = HexDigitToNum(*psz++); if (iNum == -1) return 1; if (!RT_C_IS_SPACE(ch2 = *psz) && ch2 != '\0' && ch2 != '>' && ch2 != ',' && ch2 != ';') { int iDigit = HexDigitToNum(*psz++); if (iDigit == -1) return 1; iNum = iNum * 16 + iDigit; } /* add the byte */ if (!(cb % 4 /*64*/)) { pb = (uint8_t *)RTMemRealloc(pb, cb + 64); if (!pb) { RTPrintf("%s: error: RTMemRealloc failed\n", argv[0]); return 1; } } pb[cb++] = (uint8_t)iNum; } } /* * Disassemble it. */ rc = MyDisasmBlock(argv0, enmCpuMode, uAddress, uHighlightAddr, pb, cb, enmStyle, fListing, enmUndefOp); } else { /* * Process the files. */ for ( ; iArg < argc; iArg++) { /* * Read the file into memory. */ void *pvFile; size_t cbFile; rc = RTFileReadAllEx(argv[iArg], off, cbMax, RTFILE_RDALL_O_DENY_NONE, &pvFile, &cbFile); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "%s: %s: %Rrc\n", argv0, argv[iArg], rc); break; } /* * Disassemble it. */ rc = MyDisasmBlock(argv0, enmCpuMode, uAddress, uHighlightAddr, (uint8_t *)pvFile, cbFile, enmStyle, fListing, enmUndefOp); if (RT_FAILURE(rc)) break; } } return RT_SUCCESS(rc) ? 0 : 1; }
/** * Special entrypoint used by the hardening code when something goes south. * * Display an error dialog to the user. * * @param pszWhere Indicates where the error occured. * @param enmWhat Indicates what init operation was going on at the time. * @param rc The VBox status code corresponding to the error. * @param pszMsgFmt The message format string. * @param va Format arguments. */ extern "C" DECLEXPORT(void) TrustedError(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va) { # ifdef VBOX_WS_MAC /* Hide setuid root from AppKit: */ HideSetUidRootFromAppKit(); # endif /* VBOX_WS_MAC */ char szMsgBuf[_16K]; /* * We have to create QApplication anyway just to show the only one error-message. * This is a bit hackish as we don't have the argument vector handy. */ int argc = 0; char *argv[2] = { NULL, NULL }; QApplication a(argc, &argv[0]); /* * The details starts off a properly formatted rc and where/what, we use * the szMsgBuf for this, thus this have to come before the actual message * formatting. */ RTStrPrintf(szMsgBuf, sizeof(szMsgBuf), "<!--EOM-->" "where: %s\n" "what: %d\n" "%Rra\n", pszWhere, enmWhat, rc); QString strDetails = szMsgBuf; /* * Format the error message. Take whatever comes after a double new line as * something better off in the details section. */ RTStrPrintfV(szMsgBuf, sizeof(szMsgBuf), pszMsgFmt, va); char *pszDetails = strstr(szMsgBuf, "\n\n"); if (pszDetails) { while (RT_C_IS_SPACE(*pszDetails)) *pszDetails++ = '\0'; if (*pszDetails) { strDetails += "\n"; strDetails += pszDetails; } RTStrStripR(szMsgBuf); } QString strText = QApplication::tr("<html><b>%1 (rc=%2)</b><br/><br/>").arg(szMsgBuf).arg(rc); strText.replace(QString("\n"), QString("<br>")); /* * Append possibly helpful hints to the error message. */ switch (enmWhat) { case kSupInitOp_Driver: # ifdef RT_OS_LINUX strText += g_QStrHintLinuxNoDriver; # else /* RT_OS_LINUX */ strText += g_QStrHintOtherNoDriver; # endif /* !RT_OS_LINUX */ break; # ifdef RT_OS_LINUX case kSupInitOp_IPRT: case kSupInitOp_Misc: if (rc == VERR_NO_MEMORY) strText += g_QStrHintLinuxNoMemory; else # endif /* RT_OS_LINUX */ if (rc == VERR_VM_DRIVER_VERSION_MISMATCH) # ifdef RT_OS_LINUX strText += g_QStrHintLinuxWrongDriverVersion; # else /* RT_OS_LINUX */ strText += g_QStrHintOtherWrongDriverVersion; # endif /* !RT_OS_LINUX */ else strText += g_QStrHintReinstall; break; case kSupInitOp_Integrity: case kSupInitOp_RootCheck: strText += g_QStrHintReinstall; break; default: /* no hints here */ break; }
static DECLCALLBACK(int) scriptRun(PVM pVM, RTFILE File) { RTPrintf("info: running script...\n"); uint64_t cb; int rc = RTFileGetSize(File, &cb); if (RT_SUCCESS(rc)) { if (cb == 0) return VINF_SUCCESS; if (cb < _1M) { char *pszBuf = (char *)RTMemAllocZ(cb + 1); if (pszBuf) { rc = RTFileRead(File, pszBuf, cb, NULL); if (RT_SUCCESS(rc)) { pszBuf[cb] = '\0'; /* * Now process what's in the buffer. */ char *psz = pszBuf; while (psz && *psz) { /* skip blanks. */ while (RT_C_IS_SPACE(*psz)) psz++; if (!*psz) break; /* end of line */ char *pszNext; char *pszEnd = strchr(psz, '\n'); if (!pszEnd) pszEnd = strchr(psz, '\r'); if (!pszEnd) pszNext = pszEnd = strchr(psz, '\0'); else pszNext = pszEnd + 1; if (*psz != ';' && *psz != '#' && *psz != '/') { /* strip end */ *pszEnd = '\0'; while (pszEnd > psz && RT_C_IS_SPACE(pszEnd[-1])) *--pszEnd = '\0'; /* process the line */ RTPrintf("debug: executing script line '%s'\n", psz); rc = scriptCommand(pVM, psz, pszEnd - psz); if (RT_FAILURE(rc)) { RTPrintf("error: '%s' failed: %Rrc\n", psz, rc); break; } } /* else comment line */ /* next */ psz = pszNext; } } else RTPrintf("error: failed to read script file: %Rrc\n", rc); RTMemFree(pszBuf); } else { RTPrintf("error: Out of memory. (%d bytes)\n", cb + 1); rc = VERR_NO_MEMORY; } } else RTPrintf("error: script file is too large (0x%llx bytes)\n", cb); } else RTPrintf("error: couldn't get size of script file: %Rrc\n", rc); return rc; }
/** * Change the traceing configuration of the VM. * * @returns VBox status code. * @retval VINF_SUCCESS * @retval VERR_NOT_FOUND if any of the trace point groups mentioned in the * config string cannot be found. (Or if the string cannot be made * sense of.) No change made. * @retval VERR_INVALID_VM_HANDLE * @retval VERR_INVALID_POINTER * * @param pVM The cross context VM structure. * @param pszConfig The configuration change specification. * * Trace point group names, optionally prefixed by a '-' to * indicate that the group is being disabled. A special * group 'all' can be used to enable or disable all trace * points. * * Drivers, devices and USB devices each have their own * trace point group which can be accessed by prefixing * their official PDM name by 'drv', 'dev' or 'usb' * respectively. */ VMMDECL(int) DBGFR3TraceConfig(PVM pVM, const char *pszConfig) { VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); AssertPtrReturn(pszConfig, VERR_INVALID_POINTER); if (pVM->hTraceBufR3 == NIL_RTTRACEBUF) return VERR_DBGF_NO_TRACE_BUFFER; /* * We do this in two passes, the first pass just validates the input string * and the second applies the changes. */ for (uint32_t uPass = 0; uPass < 1; uPass++) { char ch; while ((ch = *pszConfig) != '\0') { if (RT_C_IS_SPACE(ch)) continue; /* * Operation prefix. */ bool fNo = false; do { if (ch == 'n' && pszConfig[1] == 'o') { fNo = !fNo; pszConfig++; } else if (ch == '+') fNo = false; else if (ch == '-' || ch == '!' || ch == '~') fNo = !fNo; else break; } while ((ch = *++pszConfig) != '\0'); if (ch == '\0') break; /* * Extract the name. */ const char *pszName = pszConfig; while ( ch != '\0' && !RT_C_IS_SPACE(ch) && !RT_C_IS_PUNCT(ch)) ch = *++pszConfig; size_t const cchName = pszConfig - pszName; /* * 'all' - special group that enables or disables all trace points. */ if (cchName == 3 && !strncmp(pszName, "all", 3)) { if (uPass != 0) { uint32_t iCpu = pVM->cCpus; if (!fNo) while (iCpu-- > 0) pVM->aCpus[iCpu].fTraceGroups = UINT32_MAX; else while (iCpu-- > 0) pVM->aCpus[iCpu].fTraceGroups = 0; PDMR3TracingConfig(pVM, NULL, 0, !fNo, uPass > 0); } } else { /* * A specific group, try the VMM first then PDM. */ uint32_t i = RT_ELEMENTS(g_aVmmTpGroups); while (i-- > 0) if ( g_aVmmTpGroups[i].cchName == cchName && !strncmp(g_aVmmTpGroups[i].pszName, pszName, cchName)) { if (uPass != 0) { uint32_t iCpu = pVM->cCpus; if (!fNo) while (iCpu-- > 0) pVM->aCpus[iCpu].fTraceGroups |= g_aVmmTpGroups[i].fMask; else while (iCpu-- > 0) pVM->aCpus[iCpu].fTraceGroups &= ~g_aVmmTpGroups[i].fMask; } break; } if (i == UINT32_MAX) { int rc = PDMR3TracingConfig(pVM, pszName, cchName, !fNo, uPass > 0); if (RT_FAILURE(rc)) return rc; } } } } return VINF_SUCCESS; }