13 struct perf_header_attr
*perf_header_attr__new(struct perf_counter_attr
*attr
)
15 struct perf_header_attr
*self
= malloc(sizeof(*self
));
23 self
->id
= malloc(sizeof(u64
));
31 void perf_header_attr__add_id(struct perf_header_attr
*self
, u64 id
)
36 if (self
->ids
> self
->size
) {
38 self
->id
= realloc(self
->id
, self
->size
* sizeof(u64
));
49 struct perf_header
*perf_header__new(void)
51 struct perf_header
*self
= malloc(sizeof(*self
));
60 self
->attr
= malloc(sizeof(void *));
65 self
->data_offset
= 0;
71 void perf_header__add_attr(struct perf_header
*self
,
72 struct perf_header_attr
*attr
)
74 int pos
= self
->attrs
;
80 if (self
->attrs
> self
->size
) {
82 self
->attr
= realloc(self
->attr
, self
->size
* sizeof(void *));
86 self
->attr
[pos
] = attr
;
89 static const char *__perf_magic
= "PERFFILE";
91 #define PERF_MAGIC (*(u64 *)__perf_magic)
93 struct perf_file_section
{
98 struct perf_file_attr
{
99 struct perf_counter_attr attr
;
100 struct perf_file_section ids
;
103 struct perf_file_header
{
107 struct perf_file_section attrs
;
108 struct perf_file_section data
;
111 static void do_write(int fd
, void *buf
, size_t size
)
114 int ret
= write(fd
, buf
, size
);
117 die("failed to write");
124 void perf_header__write(struct perf_header
*self
, int fd
)
126 struct perf_file_header f_header
;
127 struct perf_file_attr f_attr
;
128 struct perf_header_attr
*attr
;
131 lseek(fd
, sizeof(f_header
), SEEK_SET
);
134 for (i
= 0; i
< self
->attrs
; i
++) {
135 attr
= self
->attr
[i
];
137 attr
->id_offset
= lseek(fd
, 0, SEEK_CUR
);
138 do_write(fd
, attr
->id
, attr
->ids
* sizeof(u64
));
142 self
->attr_offset
= lseek(fd
, 0, SEEK_CUR
);
144 for (i
= 0; i
< self
->attrs
; i
++) {
145 attr
= self
->attr
[i
];
147 f_attr
= (struct perf_file_attr
){
150 .offset
= attr
->id_offset
,
151 .size
= attr
->ids
* sizeof(u64
),
154 do_write(fd
, &f_attr
, sizeof(f_attr
));
158 self
->data_offset
= lseek(fd
, 0, SEEK_CUR
);
160 f_header
= (struct perf_file_header
){
162 .size
= sizeof(f_header
),
163 .attr_size
= sizeof(f_attr
),
165 .offset
= self
->attr_offset
,
166 .size
= self
->attrs
* sizeof(f_attr
),
169 .offset
= self
->data_offset
,
170 .size
= self
->data_size
,
174 lseek(fd
, 0, SEEK_SET
);
175 do_write(fd
, &f_header
, sizeof(f_header
));
176 lseek(fd
, self
->data_offset
+ self
->data_size
, SEEK_SET
);
181 static void do_read(int fd
, void *buf
, size_t size
)
184 int ret
= read(fd
, buf
, size
);
187 die("failed to read");
189 die("failed to read: missing data");
196 struct perf_header
*perf_header__read(int fd
)
198 struct perf_header
*self
= perf_header__new();
199 struct perf_file_header f_header
;
200 struct perf_file_attr f_attr
;
203 int nr_attrs
, nr_ids
, i
, j
;
205 lseek(fd
, 0, SEEK_SET
);
206 do_read(fd
, &f_header
, sizeof(f_header
));
208 if (f_header
.magic
!= PERF_MAGIC
||
209 f_header
.size
!= sizeof(f_header
) ||
210 f_header
.attr_size
!= sizeof(f_attr
))
211 die("incompatible file format");
213 nr_attrs
= f_header
.attrs
.size
/ sizeof(f_attr
);
214 lseek(fd
, f_header
.attrs
.offset
, SEEK_SET
);
216 for (i
= 0; i
< nr_attrs
; i
++) {
217 struct perf_header_attr
*attr
;
220 do_read(fd
, &f_attr
, sizeof(f_attr
));
221 tmp
= lseek(fd
, 0, SEEK_CUR
);
223 attr
= perf_header_attr__new(&f_attr
.attr
);
225 nr_ids
= f_attr
.ids
.size
/ sizeof(u64
);
226 lseek(fd
, f_attr
.ids
.offset
, SEEK_SET
);
228 for (j
= 0; j
< nr_ids
; j
++) {
229 do_read(fd
, &f_id
, sizeof(f_id
));
231 perf_header_attr__add_id(attr
, f_id
);
233 perf_header__add_attr(self
, attr
);
234 lseek(fd
, tmp
, SEEK_SET
);
237 self
->data_offset
= f_header
.data
.offset
;
238 self
->data_size
= f_header
.data
.size
;
240 lseek(fd
, self
->data_offset
+ self
->data_size
, SEEK_SET
);