void CDebuggerUI::HandleCartToRamDMA(void) { COpInfo opInfo(R4300iOp::m_Opcode); uint32_t dmaRomAddr = g_Reg->PI_CART_ADDR_REG & 0x0FFFFFFF; uint32_t dmaRamAddr = g_Reg->PI_DRAM_ADDR_REG | 0x80000000; uint32_t dmaLen = opInfo.GetStoreValueUnsigned() + 1; m_DMALog->AddEntry(dmaRomAddr, dmaRamAddr, dmaLen); // break if write breakpoint exists anywhere in target buffer if (m_Breakpoints->WriteBPExistsInChunk(dmaRamAddr, dmaLen)) { g_Settings->SaveBool(Debugger_SteppingOps, true); } }
// Called from the interpreter core at the beginning of every CPU step void CDebuggerUI::CPUStepStarted() { if (isStepping() && bCPULoggingEnabled()) { Debug_RefreshCPULogWindow(); } uint32_t pc = g_Reg->m_PROGRAM_COUNTER; COpInfo opInfo(R4300iOp::m_Opcode); if (opInfo.IsStoreCommand()) { uint32_t memoryAddress = opInfo.GetLoadStoreAddress(); if (m_Breakpoints->MemLockExists(memoryAddress, opInfo.NumBytesToStore())) { // Memory is locked, skip op g_Settings->SaveBool(Debugger_SkipOp, true); return; } } m_ScriptSystem->HookCPUExec()->InvokeByAddressInRange(pc); if (SkipOp()) { return; } m_ScriptSystem->HookCPUExecOpcode()->InvokeByAddressInRange_MaskedOpcode(pc, R4300iOp::m_Opcode.Hex); if (SkipOp()) { return; } m_ScriptSystem->HookCPUGPRValue()->InvokeByAddressInRange_GPRValue(pc); if (SkipOp()) { return; } // Memory events, pi cart -> ram dma if (opInfo.IsLoadStoreCommand()) // Read and write instructions { uint32_t memoryAddress = opInfo.GetLoadStoreAddress(); if (opInfo.IsLoadCommand()) // Read instructions { m_ScriptSystem->HookCPURead()->InvokeByAddressInRange(memoryAddress); if (SkipOp()) { return; } } else // Write instructions { m_ScriptSystem->HookCPUWrite()->InvokeByAddressInRange(memoryAddress); if (SkipOp()) { return; } if (memoryAddress == 0xA460000C) // PI_WR_LEN_REG { HandleCartToRamDMA(); } } } if (CDebugSettings::ExceptionBreakpoints() != 0) { if (pc == 0x80000000 || pc == 0x80000080 || pc == 0xA0000100 || pc == 0x80000180) { HandleCPUException(); } } if (m_Breakpoints->HaveAnyGPRWriteBP()) { int nReg = 0; opInfo.WritesGPR(&nReg); if (nReg != 0 && m_Breakpoints->HaveGPRWriteBP(nReg)) { g_Settings->SaveBool(Debugger_SteppingOps, true); } } if (m_Breakpoints->HaveAnyGPRReadBP()) { int nReg1 = 0, nReg2 = 0; opInfo.ReadsGPR(&nReg1, &nReg2); if ((nReg1 != 0 && m_Breakpoints->HaveGPRReadBP(nReg1)) || (nReg2 != 0 && m_Breakpoints->HaveGPRReadBP(nReg2))) { g_Settings->SaveBool(Debugger_SteppingOps, true); } } if (m_Breakpoints->HaveHIWriteBP() && opInfo.WritesHI() || m_Breakpoints->HaveLOWriteBP() && opInfo.WritesLO() || m_Breakpoints->HaveHIReadBP() && opInfo.ReadsHI() || m_Breakpoints->HaveLOReadBP() && opInfo.ReadsLO()) { g_Settings->SaveBool(Debugger_SteppingOps, true); } }
void HDeviceHostHttpServer::incomingSubscriptionRequest( HMessagingInfo* mi, const HSubscribeRequest& sreq) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG("Subscription received."); QUuid udn = extractUdn(sreq.eventUrl()); HServerDevice* device = !udn.isNull() ? m_deviceStorage.searchDeviceByUdn(HUdn(udn), AllDevices) : 0; HServerService* service = 0; if (!device) { // the request did not have the UDN prefix, which means that either // 1) the request was for a EventUrl that was defined as an absolute URL // in the device description or // 2) the request is invalid service = m_deviceStorage.searchServiceByEventUrl(sreq.eventUrl()); if (!service) { HLOG_WARN(QString( "Ignoring invalid event subscription to: [%1].").arg( sreq.eventUrl().toString())); mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } } else if (!service) { service = m_deviceStorage.searchServiceByEventUrl( device, extractRequestExludingUdn(sreq.eventUrl())); } if (!service) { HLOG_WARN(QString("Subscription defined as [%1] is invalid.").arg( sreq.eventUrl().path())); mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } // The UDA v1.1 does not specify what to do when a subscription is received // to a service that is not evented. A "safe" route was taken here and // all subscriptions are accepted rather than returning some error. However, // in such a case the timeout is adjusted to a day and no events are ever sent. HSid sid; StatusCode sc; if (sreq.isRenewal()) { sc = m_eventNotifier.renewSubscription(sreq, &sid); } else { sc = m_eventNotifier.addSubscriber(service, sreq, &sid); } if (sc != Ok) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(sc, *mi)); return; } HServiceEventSubscriber* subscriber = m_eventNotifier.remoteClient(sid); HSubscribeResponse response( subscriber->sid(), HSysInfo::instance().herqqProductTokens(), subscriber->timeout()); HHttpAsyncOperation* op = m_httpHandler->send(mi, HHttpMessageCreator::create(response, *mi)); if (op) { HOpInfo opInfo(service, sreq, subscriber); m_ops.append(qMakePair(QPointer<HHttpAsyncOperation>(op), opInfo)); } }
FormulaParser::Value FormulaParser::eval() { int digits = 0; bool plus = false; EvalStack stack; stack.ops.push('{'); while (int type = fnext()) { if (type == tChar && chr == ']') break; if (type == tChar && chr == '|') { type = fnext(); if (type == tNum) { digits = static_cast<int>(val); } else if (type == tChar && chr == '+') { plus = true; } fnext(); } else if (type == tName) { std::vector<std::string> parts; bool isfunc = false; while (type == tName) { parts.push_back(tag); size_t prev = pos; if ((type = fnext()) != tChar || chr != '.') { if (type == tChar && chr == '(') { isfunc = true; } else { pos = prev; } break; } type = fnext(); } std::string result = ""; for (auto& part : parts) { if (!result.empty()) result.push_back('.'); result.append(part); } if (isfunc) { char funcId = getFunction(result); OpInfo const& op = opInfo(funcId); while (stack.ops.size() && opInfo(stack.ops.top()).rprio >= op.lprio) { stack.exec(stack.ops.top()); stack.ops.pop(); } stack.ops.push(funcId); stack.needval = op.rval; } else if (!stack.ops.empty() && stack.ops.top() == funcTable) { stack.vals.push(AttributeValue(PowerTags::table(result))); } else { static re::Prog sfid("sf_(\\d+)", -1, re::Prog::CaseInsensitive); static re::Prog sftag(R"/(powertag.(\w+)."(.*)")/", -1, re::Prog::CaseInsensitive); //static re::Prog lookup(R"(table.(\w+).(\w+))", -1, re::Prog::CaseInsensitive); std::vector<std::string> match; if (context && sfid.match(result, &match)) { stack.vals.emplace(context->get(atoi(match[1].c_str()), values)); } else if (sftag.match(result, &match)) { stack.vals.emplace(PowerTags::get(match[1], match[2], values)); } else { auto it = values.find(result); stack.vals.push(it == values.end() ? 0.0 : it->second); } } stack.needval = 0; } else if (type == tTag) { auto it = values.find(tag); if (it != values.end()) { prevtag = it->second; } else if (context) { prevtag = context->get(tag, values); } else { prevtag = 0.0; } stack.vals.push(prevtag); stack.needval = 0; } else if (type == tNum) { stack.vals.push(val); stack.needval = 0; } else if (type == tChar) { if (chr == '-' && stack.needval) chr = '~'; OpInfo const& op = opInfo(chr); while (stack.ops.size() && opInfo(stack.ops.top()).rprio >= op.lprio) { char top = stack.ops.top(); stack.exec(top); stack.ops.pop(); if (opInfo(top).rprio == 0) break; } if (chr != ')') stack.ops.push(chr); stack.needval = op.rval; } } OpInfo const& op = opInfo('}'); while (stack.ops.size() && opInfo(stack.ops.top()).rprio >= op.lprio) { stack.exec(stack.ops.top()); stack.ops.pop(); } AttributeValue res; if (stack.vals.size()) res = stack.vals.top(); return Value(res, digits, plus); } std::string FormulaParser::parse() { std::string result; int newlines = 0; while (int type = next()) { if ((flags & FormatHTML) && newlines && (type != tChar || chr != '\n')) { if (newlines == 1) { result.append("<br/>"); } else { result.append("</p><p>"); } newlines = 0; } switch (type) { case tChar: if (chr == '[') { result.append(eval().format()); } else if (chr == '|') { next(); // 4 std::string lhs, rhs; while (next() == tChar && chr != ':') { lhs.push_back(chr); } while (next() == tChar && chr != ';') { rhs.push_back(chr); } if (prevtag.min != 1 || prevtag.max != 1) { result.append(rhs); } else { result.append(lhs); } } else if (chr == '\n' && (flags & FormatHTML)) { ++newlines; } else { if (flags & FormatTags) { if (chr == ' ' && (result.empty() || result.back() == '\n')) { break; } if (chr == '%') { result.push_back('%'); } } result.push_back(chr); } break; case tTag: if (tag.substr(0, 2) == "/c" || tag.substr(0, 2) == "c:" || pretags.find(tag) != pretags.end()) { if (flags & FormatHTML) { if (tag.substr(0, 2) == "/c") { result.append("</span>"); } else if (tag.substr(0, 2) == "c:") { result.append(fmtstring("<span style=\"color: #%s\">", tag.substr(4).c_str())); } else { result.append(pretags[tag]); } } else if ((flags & FormatTags) && tag == "icon:bullet") { result.push_back('*'); } } else { auto it = values.find(tag); if (it != values.end()) { prevtag = it->second; } else if (context) { prevtag = context->get(tag, values); } else { prevtag = 0.0; } result.append(Value(prevtag).format()); } break; }