#include "sys_task_req.h" #include "cray_mainframe.h" #include "cray_cpu.h" struct SysCallEntry_s { char Name[16]; uint32_t Flags; uint32_t ArgCnt; uint64_t HandlerAddr; uint64_t NumCalls; uint64_t TotalTime; uint64_t MaxTime; uint64_t MinTime; }; static CAddr_t SysCallTableBase; static size_t SysCallTableSize; void SetupSystaskParser(const Configuration_c &aConfig) { SysCallTableBase = aConfig.get("SysCallTableBase"); CAddr_t SysCallTableEnd = aConfig.get("SysCallTableEnd"); SysCallTableSize = (size_t(SysCallTableEnd) - size_t(SysCallTableBase)) / sizeof(SysCallEntry_s) * 8; } #if defined(PARTIAL_DEBUG) && defined(_MSC_VER) #pragma optimize ("", off) #endif SysCallEntry_s GetSysCallEntry(size_t aSysCallNumber, const class Mainframe_c &aMainframe) { SysCallEntry_s Entry; const size_t SysCallEntrySize = sizeof(SysCallEntry_s); for (size_t Idx = 0; Idx < SysCallEntrySize / sizeof(uint64_t); ++Idx) { ((uint64_t*)(&Entry))[Idx] = aMainframe.MemReadNoWatchpoint(CAddr_t(SysCallTableBase + (8 * aSysCallNumber + Idx))); if (Idx > 1) ((uint64_t*)(&Entry))[Idx] = SwapBytes(((uint64_t*)(&Entry))[Idx]); } return Entry; } void DumpSyscallStats(std::ostream &aLogger, const class Mainframe_c &aMainframe, OsTypes_e aOsType) { if (aOsType != OsTypes_e::UNICOS) return; for (size_t SysCall = 0; SysCall < SysCallTableSize; ++SysCall) { try { SysCallEntry_s Entry = GetSysCallEntry(SysCall, aMainframe); if (Entry.NumCalls > 0) { aLogger << "SYSCALL: " << DecPrinter(SysCall) << " " << Entry.Name << " # calls: " << DecPrinter(Entry.NumCalls); aLogger << " total time: " << DecPrinter(Entry.TotalTime); aLogger << " max time: " << DecPrinter(Entry.MaxTime); aLogger << " min time: " << DecPrinter(Entry.MinTime); aLogger << std::endl; } } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } } void PrintString(std::ostream &aLogger, CAddr_t aAddr, const Mainframe_c &aMainframe) { aLogger << "\""; try { bool Done = false; while (!Done) { uint64_t Data = aMainframe.MemReadNoWatchpoint(aAddr); char *Str = (char *)(&Data); for (size_t Idx = 0; Idx < 8; ++Idx) { if (Str[Idx] == 0) { Done = true; break; } aLogger << Str[Idx]; } aAddr = aAddr + 1; }; } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } aLogger << "\""; } void PrintMemDump(std::ostream &aLogger, CAddr_t aAddr, size_t aSize, const Mainframe_c &aMainframe) { aLogger << "\""; try { for (size_t i = 0; i < aSize;) { uint64_t Data = aMainframe.MemReadNoWatchpoint(aAddr); char *Str = (char *)(&Data); for (size_t Idx = 0; Idx < 8; ++Idx, ++i) { aLogger << PrintableChar(Str[Idx]); if (i >= aSize) break; } aAddr = aAddr + 1; }; } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } aLogger << "\" "; bool Done = false; try { for (size_t i = 0; i < aSize;) { uint64_t Data = aMainframe.MemReadNoWatchpoint(aAddr); char *Str = (char *)(&Data); for (size_t Idx = 0; Idx < 8; ++Idx, ++i) { aLogger << HexPrinter(Str[Idx], 2) << " "; if (i >= aSize) break; } aAddr = aAddr + 1; }; } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } void PrintMemArrayArg(std::ostream &aLogger, size_t aArg, size_t aSizeArg, const ExchangePacket_c &aExchangePacket, const Mainframe_c &aMainframe) { CInt_t S1 = aExchangePacket.GetS(1); CAddr_t DataBase = aExchangePacket.GetDataBaseAddr(); CAddr_t Args = CAddr_t(S1) + DataBase; try { CAddr_t Addr = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(CAddr_t(Args + aArg)))); CAddr_t Size = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(CAddr_t(Args + aSizeArg)))); aLogger << HexPrinter(Addr) << " (" << HexPrinter(Addr + DataBase) << "), len: " << DecPrinter(Size); if (Size < 256) { aLogger << " content: "; PrintMemDump(aLogger, Addr + DataBase, Size, aMainframe); } } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } void PrintStringArg(std::ostream &aLogger, size_t aArg, const ExchangePacket_c &aExchangePacket, const Mainframe_c &aMainframe) { CInt_t S1 = aExchangePacket.GetS(1); CAddr_t DataBase = aExchangePacket.GetDataBaseAddr(); CAddr_t Args = CAddr_t(S1) + DataBase; try { CAddr_t Addr = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(CAddr_t(Args + aArg)))); aLogger << HexPrinter(Addr) << " (" << HexPrinter(Addr + DataBase) << ") "; PrintString(aLogger, Addr + DataBase, aMainframe); } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } void PrintStringArrayArg(std::ostream &aLogger, size_t aArg, const ExchangePacket_c &aExchangePacket, const Mainframe_c &aMainframe) { CInt_t S1 = aExchangePacket.GetS(1); CAddr_t DataBase = aExchangePacket.GetDataBaseAddr(); CAddr_t Args = CAddr_t(S1) + DataBase; try { CAddr_t ArrAddr = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(CAddr_t(Args + aArg)))); aLogger << HexPrinter(ArrAddr) << " (" << HexPrinter(ArrAddr + DataBase) << ") "; if (ArrAddr != 0) { aLogger << " [ "; bool First = true; CAddr_t Ptr = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(ArrAddr + DataBase))); while (Ptr != 0) { if (!First) aLogger << " , "; First = false; aLogger << HexPrinter(Ptr) << " (" << HexPrinter(Ptr + DataBase) << ") "; PrintString(aLogger, Ptr + DataBase, aMainframe); ++ArrAddr; Ptr = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(ArrAddr + DataBase))); } aLogger << " ]"; } } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } void PrintPtrArg(std::ostream &aLogger, size_t aArg, const ExchangePacket_c &aExchangePacket, const Mainframe_c &aMainframe) { CInt_t S1 = aExchangePacket.GetS(1); CAddr_t DataBase = aExchangePacket.GetDataBaseAddr(); CAddr_t Args = CAddr_t(S1) + DataBase; try { CAddr_t Addr = CAddr_t(SwapBytes(aMainframe.MemReadNoWatchpoint(CAddr_t(Args + aArg)))); aLogger << HexPrinter(Addr) << " (" << HexPrinter(Addr + DataBase) << ") --> " << HexPrinter(SwapBytes(aMainframe.MemReadNoWatchpoint(Addr + DataBase))); } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } void PrintIntArg(std::ostream &aLogger, size_t aArg, const ExchangePacket_c &aExchangePacket, const Mainframe_c &aMainframe) { CInt_t S1 = aExchangePacket.GetS(1); CAddr_t DataBase = aExchangePacket.GetDataBaseAddr(); CAddr_t Args = CAddr_t(S1) + DataBase; try { CInt_t Data = (SwapBytes(aMainframe.MemReadNoWatchpoint(CAddr_t(Args + aArg)))); aLogger << HexPrinter(Data) << " (" << DecPrinter(Data) << ")"; } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } void ParseUnicosExchangePacket(const ExchangePacket_c &aCurrentEP, const ExchangePacket_c &aNewEP, std::ostream &aLogger, const Cpu_c &aCpu) { static size_t LastSysCall = SIZE_MAX; const Mainframe_c &Mainframe = aCpu.GetMainframe(); if (aCurrentEP.GetMode().IsMonitorMode()) { CInt_t S[8]; for (size_t Idx = 0; Idx(Args + ArgIdx) ) ); } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << " ~~~ invalid ~~~ "; } } break; } aLogger << ")"; } catch (Mainframe_c::ReadOutOfBoundsError_x &) { aLogger << "SYSCALL: ~~~ invalid ~~~ "; } } else { //aLogger << "XA: " << HexPrinter(aCpu.GetExchangePacketAddress()) << " " << "IBA: " << HexPrinter(aCurrentEP.GetInstBaseAddr()) << " "; //aLogger << "unknown SYSCALL with S0 = " << HexPrinter(S[0]); } } } } #if defined(PARTIAL_DEBUG) && defined(_MSC_VER) #pragma optimize ("", on) #endif void ParseCosExchangePacket(const ExchangePacket_c &aExchangePacket, std::ostream &aLogger, const class Mainframe_c &aMainframe) { CInt_t S[8]; for(size_t Idx=0;Idx