@@ -166,13 +166,31 @@ event_reg(uint32_t fd, const char *command, uint32_t *write, uint32_t *enabled)
166166	reg .enable_size  =  sizeof (* enabled ); // uint8_t 
167167	// reg.flags //uint16_t 
168168	reg .enable_addr  =  (uint64_t )enabled ; // uint64_t 
169- 	reg .name_args  =  (uint64_t )command ; // uint64_t 
170169
171- 	if  (ioctl (fd , DIAG_IOCSREG , & reg ) ==  -1 )
170+ 	// Hard-coded format as per the documentation 
171+ 	const  char  * format  =  "u8 version; u16 event_id; __rel_loc u8[] extension; __rel_loc u8[] payload; __rel_loc u8[] meta" ;
172+ 
173+ 	// Dynamically allocate space for name_args 
174+ 	size_t  name_args_size  =  strlen (command ) +  strlen (format ) +  2 ; // +2 for space and null terminator 
175+ 	char  * name_args  =  (char  * )malloc (name_args_size );
176+ 	if  (!name_args )
177+ 		return  -1 ; // Memory allocation failed 
178+ 
179+ 	if  (snprintf (name_args , name_args_size , "%s %s" , command , format ) >= name_args_size ) {
180+ 		free (name_args );
181+ 		return  -1 ; // Name and format combination is too long 
182+ 	}
183+ 
184+ 	reg .name_args  =  (uint64_t )name_args ; // uint64_t 
185+ 
186+ 	if  (ioctl (fd , DIAG_IOCSREG , & reg ) ==  -1 ) {
187+ 		free (name_args );
172188		return  -1 ;
189+ 	}
173190
174191	* write  =  reg .write_index ; // uint32_t 
175192
193+ 	free (name_args );
176194	return  0 ;
177195#else  // HAVE_LINUX_USER_EVENTS_H 
178196	// Not Supported 
@@ -624,6 +642,158 @@ ep_session_write_all_buffers_to_file (EventPipeSession *session, bool *events_wr
624642	return  !ep_file_has_errors  (session -> file );
625643}
626644
645+ bool 
646+ ep_tracepoint_write  (
647+ 	EventPipeSession  * session ,
648+ 	ep_rt_thread_handle_t  thread ,
649+ 	EventPipeEvent  * ep_event ,
650+ 	EventPipeEventPayload  * ep_event_payload ,
651+ 	const  uint8_t  * activity_id ,
652+ 	const  uint8_t  * related_activity_id ,
653+ 	ep_rt_thread_handle_t  event_thread ,
654+ 	EventPipeStackContents  * stack )
655+ {
656+ #ifdef  HAVE_SYS_UIO_H 
657+ 	EventPipeProvider  * provider  =  ep_event_get_provider  (ep_event );
658+ 
659+ 	EventPipeSessionProviderList  * session_provider_list  =  ep_session_get_providers  (session );
660+ 	EventPipeSessionProvider  * session_provider  =  ep_session_provider_list_find_by_name  (ep_session_provider_list_get_providers  (session_provider_list ), ep_provider_get_provider_name  (provider ));
661+ 
662+ 	uint32_t  event_id  =  ep_event_get_event_id  (ep_event );
663+ 
664+ 	dn_umap_t  * event_id_to_tracepoint_map  =  ep_session_provider_get_event_id_to_tracepoint_map  (session_provider );
665+ 	dn_umap_it_t  found1  =  dn_umap_find  (event_id_to_tracepoint_map , & event_id );
666+ 	EventPipeTracepoint  * tracepoint  =  NULL ;
667+ 	if  (dn_umap_it_end  (found1 )) {
668+ 		// If we don't have a tracepoint for this event_id, use the default tracepoint 
669+ 		tracepoint  =  session_provider -> default_tracepoint ;
670+ 	} else  {
671+ 		// We have a tracepoint for this event_id 
672+ 		tracepoint  =  dn_umap_it_value_t  (found1 , EventPipeTracepoint  * );
673+ 	}
674+ 	if  (tracepoint  ==  NULL ) {
675+ 		// No tracepoint for this event_id and no default tracepoint, so we can't write the event. 
676+ 		return  false;
677+ 	}
678+ 
679+ 	if  (tracepoint -> enabled  ==  0 ) {
680+ 		// No listeners 
681+ 		return  false;
682+ 	}
683+ 
684+ 	struct  iovec  io [9 ];
685+ 
686+ 	io [0 ].iov_base  =  & tracepoint -> write_index ;      // __u32 from event_reg 
687+ 	io [0 ].iov_len  =  sizeof (tracepoint -> write_index );
688+ 
689+ 	uint8_t  version  =  0x01 ; // hardcoded for the first tracepoint format version 
690+ 	io [1 ].iov_base  =  & version ;
691+ 	io [1 ].iov_len  =  sizeof (version );
692+ 
693+ 	uint16_t  truncated_event_id  =  event_id  &  0xFFFF ;
694+ 	io [2 ].iov_base  =  & truncated_event_id ;
695+ 	io [2 ].iov_len  =  sizeof (truncated_event_id );
696+ 
697+ 	// The data transmitted in version 1 is 
698+ 	// extension - a NetTrace V6 LabelList 
699+ 	// payload - the EventPipe Event Payload 
700+ 	// meta - the EventPipe Event metadata 
701+ 
702+ 	bool  activity_id_is_empty  =  true;
703+ 	if  (activity_id  !=  NULL ) {
704+ 		// If the activity_id is not empty, then we don't consider it empty. 
705+ 		for  (int  i  =  0 ; i  <  EP_ACTIVITY_ID_SIZE ; ++ i ) {
706+ 			if  (activity_id [i ] !=  0 ) {
707+ 				activity_id_is_empty  =  false;
708+ 				break ;
709+ 			}
710+ 		}
711+ 	}
712+ 	bool  related_activity_id_is_empty  =  true;
713+ 	if  (related_activity_id  !=  NULL ) {
714+ 		// If the related_activity_id is not empty, then we don't consider it empty. 
715+ 		for  (int  i  =  0 ; i  <  EP_ACTIVITY_ID_SIZE ; ++ i ) {
716+ 			if  (related_activity_id [i ] !=  0 ) {
717+ 				related_activity_id_is_empty  =  false;
718+ 				break ;
719+ 			}
720+ 		}
721+ 	}
722+ 	// extension generation helper 
723+ 	uint16_t  extension_len  =  0 ;
724+ 	if  (activity_id  !=  NULL  &&  !activity_id_is_empty )
725+ 		extension_len  +=  1  +  EP_ACTIVITY_ID_SIZE ; // ActivityId kind + value 
726+ 	if  (related_activity_id  !=  NULL  &&  !related_activity_id_is_empty )
727+ 		extension_len  +=  1  +  EP_ACTIVITY_ID_SIZE ; // RelatedActivityId kind + value 
728+ 
729+ 	uint8_t  * extension  =  NULL ;
730+ 	if  (extension_len  >  0 ) {
731+ 		extension  =  (uint8_t  * )malloc (extension_len );
732+ 		EP_ASSERT (extension  !=  NULL );
733+ 		uint16_t  offset  =  0 ;
734+ 		if  (activity_id  !=  NULL  &&  !activity_id_is_empty ) {
735+ 			// If there is a related_activity_id, use 0x81 (more follows), else 0x01 (no more follows) 
736+ 			extension [offset ] =  (related_activity_id  !=  NULL  &&  !related_activity_id_is_empty ) ? 0x81  : 0x01 ;
737+ 			memcpy (extension  +  offset  +  1 , activity_id , EP_ACTIVITY_ID_SIZE );
738+ 			offset  +=  1  +  EP_ACTIVITY_ID_SIZE ;
739+ 		}
740+ 		if  (related_activity_id  !=  NULL  &&  !related_activity_id_is_empty ) {
741+ 			// RelatedActivityId: 0x02 (no more follows) 
742+ 			extension [offset ] =  0x02 ;
743+ 			memcpy (extension  +  offset  +  1 , related_activity_id , EP_ACTIVITY_ID_SIZE );
744+ 			offset  +=  1  +  EP_ACTIVITY_ID_SIZE ;
745+ 		}
746+ 	}
747+ 
748+ 	uint32_t  payload_len  =  ep_event_payload_get_size  (ep_event_payload );
749+ 	if  ((payload_len  &  0xFFFF0000 ) !=  0 ) {
750+ 		// Payload is too large, we can't write it. 
751+ 		return  false;
752+ 	}
753+ 	uint8_t  * payload  =  (uint8_t  * )malloc  (payload_len );
754+ 	EP_ASSERT  (payload  !=  NULL );
755+ 	ep_event_payload_copy_data  (ep_event_payload , payload );
756+ 
757+ 	// meta 
758+ 	const  uint8_t  * metadata  =  ep_event_get_metadata  (ep_event );
759+ 	uint32_t  metadata_len  =  ep_event_get_metadata_len  (ep_event );
760+ 
761+ 	// calculated __rel_loc values 
762+ 	uint32_t  meta_rel_loc  =  metadata_len  << 16  | ((extension_len  +  payload_len ) &  0xFFFF );
763+ 	uint32_t  payload_rel_loc  =  payload_len  << 16  | ((sizeof (meta_rel_loc ) +  extension_len ) &  0xFFFF );
764+ 	uint32_t  extension_rel_loc  =  extension_len  << 16  | ((sizeof (payload_rel_loc ) +  sizeof (meta_rel_loc )) &  0xFFFF );
765+ 	io [3 ].iov_base  =  & extension_rel_loc ;
766+ 	io [3 ].iov_len  =  sizeof (extension_rel_loc );
767+ 
768+ 	io [4 ].iov_base  =  & payload_rel_loc ;
769+ 	io [4 ].iov_len  =  sizeof (payload_rel_loc );
770+ 
771+ 	io [5 ].iov_base  =  & meta_rel_loc ;
772+ 	io [5 ].iov_len  =  sizeof (meta_rel_loc );
773+ 
774+ 	// Actual data buffers 
775+ 	io [6 ].iov_base  =  extension ;
776+ 	io [6 ].iov_len  =  extension_len ;
777+ 
778+ 	io [7 ].iov_base  =  payload ;
779+ 	io [7 ].iov_len  =  payload_len ;
780+ 
781+ 	io [8 ].iov_base  =  (void  * )metadata ;
782+ 	io [8 ].iov_len  =  metadata_len ;
783+ 	int32_t  result  =  writev (session -> user_events_data_fd , (const  struct  iovec  * )io , 9 );
784+ 	if  (result  ==  -1 ) {
785+ 		// Failed to write the event, return false. 
786+ 		// return false; 
787+ 		return  false;
788+ 	}
789+ 
790+ 	return  true;
791+ #else  // HAVE_SYS_UIO_H 
792+ 	// Not Supported 
793+ 	return  false;
794+ #endif  // HAVE_SYS_UIO_H 
795+ }
796+ 
627797bool 
628798ep_session_write_event  (
629799	EventPipeSession  * session ,
@@ -661,6 +831,17 @@ ep_session_write_event (
661831				stack  ==  NULL  ? NULL  : (uintptr_t  * )ep_stack_contents_get_pointer  (stack ),
662832				session -> callback_additional_data );
663833			result  =  true;
834+ 		} else  if  (session -> session_type  ==  EP_SESSION_TYPE_USEREVENTS ) {
835+ 			EP_ASSERT  (session -> user_events_data_fd  !=  0 );
836+ 			result  =  ep_tracepoint_write  (
837+ 				session ,
838+ 				thread ,
839+ 				ep_event ,
840+ 				payload ,
841+ 				activity_id ,
842+ 				related_activity_id ,
843+ 				event_thread ,
844+ 				stack );
664845		} else  {
665846			EP_ASSERT  (session -> buffer_manager  !=  NULL );
666847			result  =  ep_buffer_manager_write_event  (
0 commit comments