1- use std:: io:: Read ;
1+ use std:: io:: { Read , Seek , SeekFrom } ;
22
33use byteorder:: { ByteOrder , ReadBytesExt } ;
44
55use super :: features:: FeatureSet ;
66use super :: section:: PerfFileSection ;
77
8+ const MAGIC_SIZE : usize = 8 ;
9+
810/// `perf_header`
911///
1012/// The magic number identifies the perf file and the version. Current perf versions
@@ -14,7 +16,7 @@ use super::section::PerfFileSection;
1416/// endian.
1517#[ derive( Debug , Clone , Copy ) ]
1618pub struct PerfHeader {
17- pub magic : [ u8 ; 8 ] ,
19+ pub magic : [ u8 ; MAGIC_SIZE ] ,
1820 /// size of the header
1921 #[ allow( dead_code) ]
2022 pub header_size : u64 ,
@@ -28,8 +30,8 @@ pub struct PerfHeader {
2830}
2931
3032impl PerfHeader {
31- pub fn parse < R : Read > ( mut reader : R ) -> Result < Self , std:: io:: Error > {
32- let mut magic = [ 0 ; 8 ] ;
33+ pub fn parse < R : Read + Seek > ( mut reader : R ) -> Result < Self , std:: io:: Error > {
34+ let mut magic = [ 0 ; MAGIC_SIZE ] ;
3335 reader. read_exact ( & mut magic) ?;
3436
3537 if magic[ 0 ] == b'P' {
@@ -39,9 +41,9 @@ impl PerfHeader {
3941 }
4042 }
4143
42- fn parse_impl < R : Read , T : ByteOrder > (
44+ fn parse_impl < R : Read + Seek , T : ByteOrder > (
4345 mut reader : R ,
44- magic : [ u8 ; 8 ] ,
46+ magic : [ u8 ; MAGIC_SIZE ] ,
4547 ) -> Result < Self , std:: io:: Error > {
4648 let header_size = reader. read_u64 :: < T > ( ) ?;
4749 let attr_size = reader. read_u64 :: < T > ( ) ?;
@@ -54,6 +56,14 @@ impl PerfHeader {
5456 reader. read_u64 :: < T > ( ) ?,
5557 reader. read_u64 :: < T > ( ) ?,
5658 ] ) ;
59+
60+ // Skip any additional header bytes from newer formats. Size excludes magic.
61+ let known_size = ( std:: mem:: size_of :: < Self > ( ) - MAGIC_SIZE ) as u64 ;
62+ if header_size > known_size {
63+ let extra_bytes = header_size - known_size;
64+ reader. seek ( SeekFrom :: Current ( extra_bytes as i64 ) ) ?;
65+ }
66+
5767 Ok ( Self {
5868 magic,
5969 header_size,
@@ -74,22 +84,31 @@ impl PerfHeader {
7484/// file sections.
7585#[ derive( Debug , Clone , Copy ) ]
7686pub struct PerfPipeHeader {
77- pub magic : [ u8 ; 8 ] ,
87+ pub magic : [ u8 ; MAGIC_SIZE ] ,
7888 /// size of the header (should be 16)
7989 #[ allow( dead_code) ]
8090 pub size : u64 ,
8191}
8292
8393impl PerfPipeHeader {
8494 pub fn parse < R : Read > ( mut reader : R ) -> Result < Self , std:: io:: Error > {
85- let mut magic = [ 0 ; 8 ] ;
95+ let mut magic = [ 0 ; MAGIC_SIZE ] ;
8696 reader. read_exact ( & mut magic) ?;
8797
8898 let size = if magic[ 0 ] == b'P' {
8999 reader. read_u64 :: < byteorder:: LittleEndian > ( ) ?
90100 } else {
91101 reader. read_u64 :: < byteorder:: BigEndian > ( ) ?
92102 } ;
103+
104+ // Skip any additional header bytes from newer formats. size excludes magic.
105+ // Use io::copy to sink instead of seek since pipe mode doesn't support seeking.
106+ let known_size = ( std:: mem:: size_of :: < Self > ( ) - MAGIC_SIZE ) as u64 ;
107+ if size > known_size {
108+ let extra_bytes = size - known_size;
109+ std:: io:: copy ( & mut reader. by_ref ( ) . take ( extra_bytes) , & mut std:: io:: sink ( ) ) ?;
110+ }
111+
93112 Ok ( Self { magic, size } )
94113 }
95114}
0 commit comments