// // Copyright © 2019 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include #include namespace arm { namespace pipe { //Array of member functions, the array index matches the decl_id const TimelineCaptureCommandHandler::ReadFunction TimelineCaptureCommandHandler::m_ReadFunctions[] { &TimelineCaptureCommandHandler::ReadLabel, // Label decl_id = 0 &TimelineCaptureCommandHandler::ReadEntity, // Entity decl_id = 1 &TimelineCaptureCommandHandler::ReadEventClass, // EventClass decl_id = 2 &TimelineCaptureCommandHandler::ReadRelationship, // Relationship decl_id = 3 &TimelineCaptureCommandHandler::ReadEvent // Event decl_id = 4 }; void TimelineCaptureCommandHandler::SetThreadIdSize(uint32_t size) { m_ThreadIdSize = size; } void TimelineCaptureCommandHandler::operator()(const arm::pipe::Packet& packet) { ParseData(packet); } void TimelineCaptureCommandHandler::ParseData(const arm::pipe::Packet& packet) { uint32_t offset = 0; m_PacketLength = packet.GetLength(); // We are expecting TimelineDirectoryCaptureCommandHandler to set the thread id size // if it not set in the constructor if (m_ThreadIdSize == 0) { ARM_PIPE_LOG(error) << "TimelineCaptureCommandHandler: m_ThreadIdSize has not been set"; return; } if (packet.GetLength() < 8) { return; } const unsigned char* data = reinterpret_cast(packet.GetData()); uint32_t declId = 0; while ( offset < m_PacketLength ) { declId = arm::pipe::ReadUint32(data, offset); offset += uint32_t_size; ITimelineDecoder::TimelineStatus status = (this->*m_ReadFunctions[declId])(data, offset); if (status == ITimelineDecoder::TimelineStatus::TimelineStatus_Fail) { ARM_PIPE_LOG(error) << "Decode of timeline message type [" << declId << "] at offset [" << offset << "] failed"; break; } } } ITimelineDecoder::TimelineStatus TimelineCaptureCommandHandler::ReadLabel(const unsigned char* data, uint32_t& offset) { ITimelineDecoder::Label label; label.m_Guid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; uint32_t nameLength = arm::pipe::ReadUint32(data, offset); offset += uint32_t_size; uint32_t i = 0; // nameLength - 1 to account for null operator \0 for ( i = 0; i < nameLength - 1; ++i ) { label.m_Name += static_cast(arm::pipe::ReadUint8(data, offset + i)); } // Shift offset past nameLength uint32_t uint32WordAmount = (nameLength / uint32_t_size) + (nameLength % uint32_t_size != 0 ? 1 : 0); offset += uint32WordAmount * uint32_t_size; return m_TimelineDecoder.CreateLabel(label); } ITimelineDecoder::TimelineStatus TimelineCaptureCommandHandler::ReadEntity( const unsigned char* data, uint32_t& offset) { ITimelineDecoder::Entity entity; entity.m_Guid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; return m_TimelineDecoder.CreateEntity(entity); } ITimelineDecoder::TimelineStatus TimelineCaptureCommandHandler::ReadEventClass( const unsigned char* data, uint32_t& offset) { ITimelineDecoder::EventClass eventClass; eventClass.m_Guid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; eventClass.m_NameGuid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; return m_TimelineDecoder.CreateEventClass(eventClass); } ITimelineDecoder::TimelineStatus TimelineCaptureCommandHandler::ReadRelationship( const unsigned char* data, uint32_t& offset) { ITimelineDecoder::Relationship relationship; relationship.m_RelationshipType = static_cast(arm::pipe::ReadUint32(data, offset)); offset += uint32_t_size; relationship.m_Guid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; relationship.m_HeadGuid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; relationship.m_TailGuid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; relationship.m_AttributeGuid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; return m_TimelineDecoder.CreateRelationship(relationship); } ITimelineDecoder::TimelineStatus TimelineCaptureCommandHandler::ReadEvent( const unsigned char* data, uint32_t& offset) { ITimelineDecoder::Event event; event.m_TimeStamp = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; if ( m_ThreadIdSize == 4 ) { event.m_ThreadId = arm::pipe::ReadUint32(data, offset); } else if ( m_ThreadIdSize == 8 ) { event.m_ThreadId = arm::pipe::ReadUint64(data, offset); } offset += m_ThreadIdSize; event.m_Guid = arm::pipe::ReadUint64(data, offset); offset += uint64_t_size; return m_TimelineDecoder.CreateEvent(event); } } //namespace pipe } //namespace arm