header.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211
  1. #define _FILE_OFFSET_BITS 64
  2. #include <sys/types.h>
  3. #include <byteswap.h>
  4. #include <unistd.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <linux/list.h>
  8. #include <linux/kernel.h>
  9. #include "util.h"
  10. #include "header.h"
  11. #include "../perf.h"
  12. #include "trace-event.h"
  13. #include "session.h"
  14. #include "symbol.h"
  15. #include "debug.h"
  16. /*
  17. * Create new perf.data header attribute:
  18. */
  19. struct perf_header_attr *perf_header_attr__new(struct perf_event_attr *attr)
  20. {
  21. struct perf_header_attr *self = malloc(sizeof(*self));
  22. if (self != NULL) {
  23. self->attr = *attr;
  24. self->ids = 0;
  25. self->size = 1;
  26. self->id = malloc(sizeof(u64));
  27. if (self->id == NULL) {
  28. free(self);
  29. self = NULL;
  30. }
  31. }
  32. return self;
  33. }
  34. void perf_header_attr__delete(struct perf_header_attr *self)
  35. {
  36. free(self->id);
  37. free(self);
  38. }
  39. int perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
  40. {
  41. int pos = self->ids;
  42. self->ids++;
  43. if (self->ids > self->size) {
  44. int nsize = self->size * 2;
  45. u64 *nid = realloc(self->id, nsize * sizeof(u64));
  46. if (nid == NULL)
  47. return -1;
  48. self->size = nsize;
  49. self->id = nid;
  50. }
  51. self->id[pos] = id;
  52. return 0;
  53. }
  54. int perf_header__init(struct perf_header *self)
  55. {
  56. self->size = 1;
  57. self->attr = malloc(sizeof(void *));
  58. return self->attr == NULL ? -ENOMEM : 0;
  59. }
  60. void perf_header__exit(struct perf_header *self)
  61. {
  62. int i;
  63. for (i = 0; i < self->attrs; ++i)
  64. perf_header_attr__delete(self->attr[i]);
  65. free(self->attr);
  66. }
  67. int perf_header__add_attr(struct perf_header *self,
  68. struct perf_header_attr *attr)
  69. {
  70. if (self->frozen)
  71. return -1;
  72. if (self->attrs == self->size) {
  73. int nsize = self->size * 2;
  74. struct perf_header_attr **nattr;
  75. nattr = realloc(self->attr, nsize * sizeof(void *));
  76. if (nattr == NULL)
  77. return -1;
  78. self->size = nsize;
  79. self->attr = nattr;
  80. }
  81. self->attr[self->attrs++] = attr;
  82. return 0;
  83. }
  84. static int event_count;
  85. static struct perf_trace_event_type *events;
  86. int perf_header__push_event(u64 id, const char *name)
  87. {
  88. if (strlen(name) > MAX_EVENT_NAME)
  89. pr_warning("Event %s will be truncated\n", name);
  90. if (!events) {
  91. events = malloc(sizeof(struct perf_trace_event_type));
  92. if (events == NULL)
  93. return -ENOMEM;
  94. } else {
  95. struct perf_trace_event_type *nevents;
  96. nevents = realloc(events, (event_count + 1) * sizeof(*events));
  97. if (nevents == NULL)
  98. return -ENOMEM;
  99. events = nevents;
  100. }
  101. memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
  102. events[event_count].event_id = id;
  103. strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1);
  104. event_count++;
  105. return 0;
  106. }
  107. char *perf_header__find_event(u64 id)
  108. {
  109. int i;
  110. for (i = 0 ; i < event_count; i++) {
  111. if (events[i].event_id == id)
  112. return events[i].name;
  113. }
  114. return NULL;
  115. }
  116. static const char *__perf_magic = "PERFFILE";
  117. #define PERF_MAGIC (*(u64 *)__perf_magic)
  118. struct perf_file_attr {
  119. struct perf_event_attr attr;
  120. struct perf_file_section ids;
  121. };
  122. void perf_header__set_feat(struct perf_header *self, int feat)
  123. {
  124. set_bit(feat, self->adds_features);
  125. }
  126. bool perf_header__has_feat(const struct perf_header *self, int feat)
  127. {
  128. return test_bit(feat, self->adds_features);
  129. }
  130. static int do_write(int fd, const void *buf, size_t size)
  131. {
  132. while (size) {
  133. int ret = write(fd, buf, size);
  134. if (ret < 0)
  135. return -errno;
  136. size -= ret;
  137. buf += ret;
  138. }
  139. return 0;
  140. }
  141. #define NAME_ALIGN 64
  142. static int write_padded(int fd, const void *bf, size_t count,
  143. size_t count_aligned)
  144. {
  145. static const char zero_buf[NAME_ALIGN];
  146. int err = do_write(fd, bf, count);
  147. if (!err)
  148. err = do_write(fd, zero_buf, count_aligned - count);
  149. return err;
  150. }
  151. #define dsos__for_each_with_build_id(pos, head) \
  152. list_for_each_entry(pos, head, node) \
  153. if (!pos->has_build_id) \
  154. continue; \
  155. else
  156. static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
  157. u16 misc, int fd)
  158. {
  159. struct dso *pos;
  160. dsos__for_each_with_build_id(pos, head) {
  161. int err;
  162. struct build_id_event b;
  163. size_t len;
  164. if (!pos->hit)
  165. continue;
  166. len = pos->long_name_len + 1;
  167. len = ALIGN(len, NAME_ALIGN);
  168. memset(&b, 0, sizeof(b));
  169. memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
  170. b.pid = pid;
  171. b.header.misc = misc;
  172. b.header.size = sizeof(b) + len;
  173. err = do_write(fd, &b, sizeof(b));
  174. if (err < 0)
  175. return err;
  176. err = write_padded(fd, pos->long_name,
  177. pos->long_name_len + 1, len);
  178. if (err < 0)
  179. return err;
  180. }
  181. return 0;
  182. }
  183. static int dsos__write_buildid_table(struct perf_header *header, int fd)
  184. {
  185. struct perf_session *session = container_of(header,
  186. struct perf_session, header);
  187. struct rb_node *nd;
  188. int err = 0;
  189. u16 kmisc, umisc;
  190. for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) {
  191. struct kernel_info *pos = rb_entry(nd, struct kernel_info,
  192. rb_node);
  193. if (is_host_kernel(pos)) {
  194. kmisc = PERF_RECORD_MISC_KERNEL;
  195. umisc = PERF_RECORD_MISC_USER;
  196. } else {
  197. kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
  198. umisc = PERF_RECORD_MISC_GUEST_USER;
  199. }
  200. err = __dsos__write_buildid_table(&pos->dsos__kernel, pos->pid,
  201. kmisc, fd);
  202. if (err == 0)
  203. err = __dsos__write_buildid_table(&pos->dsos__user,
  204. pos->pid, umisc, fd);
  205. if (err)
  206. break;
  207. }
  208. return err;
  209. }
  210. int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
  211. const char *name, bool is_kallsyms)
  212. {
  213. const size_t size = PATH_MAX;
  214. char *filename = malloc(size),
  215. *linkname = malloc(size), *targetname;
  216. int len, err = -1;
  217. if (filename == NULL || linkname == NULL)
  218. goto out_free;
  219. len = snprintf(filename, size, "%s%s%s",
  220. debugdir, is_kallsyms ? "/" : "", name);
  221. if (mkdir_p(filename, 0755))
  222. goto out_free;
  223. snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id);
  224. if (access(filename, F_OK)) {
  225. if (is_kallsyms) {
  226. if (copyfile("/proc/kallsyms", filename))
  227. goto out_free;
  228. } else if (link(name, filename) && copyfile(name, filename))
  229. goto out_free;
  230. }
  231. len = snprintf(linkname, size, "%s/.build-id/%.2s",
  232. debugdir, sbuild_id);
  233. if (access(linkname, X_OK) && mkdir_p(linkname, 0755))
  234. goto out_free;
  235. snprintf(linkname + len, size - len, "/%s", sbuild_id + 2);
  236. targetname = filename + strlen(debugdir) - 5;
  237. memcpy(targetname, "../..", 5);
  238. if (symlink(targetname, linkname) == 0)
  239. err = 0;
  240. out_free:
  241. free(filename);
  242. free(linkname);
  243. return err;
  244. }
  245. static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
  246. const char *name, const char *debugdir,
  247. bool is_kallsyms)
  248. {
  249. char sbuild_id[BUILD_ID_SIZE * 2 + 1];
  250. build_id__sprintf(build_id, build_id_size, sbuild_id);
  251. return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms);
  252. }
  253. int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
  254. {
  255. const size_t size = PATH_MAX;
  256. char *filename = malloc(size),
  257. *linkname = malloc(size);
  258. int err = -1;
  259. if (filename == NULL || linkname == NULL)
  260. goto out_free;
  261. snprintf(linkname, size, "%s/.build-id/%.2s/%s",
  262. debugdir, sbuild_id, sbuild_id + 2);
  263. if (access(linkname, F_OK))
  264. goto out_free;
  265. if (readlink(linkname, filename, size) < 0)
  266. goto out_free;
  267. if (unlink(linkname))
  268. goto out_free;
  269. /*
  270. * Since the link is relative, we must make it absolute:
  271. */
  272. snprintf(linkname, size, "%s/.build-id/%.2s/%s",
  273. debugdir, sbuild_id, filename);
  274. if (unlink(linkname))
  275. goto out_free;
  276. err = 0;
  277. out_free:
  278. free(filename);
  279. free(linkname);
  280. return err;
  281. }
  282. static int dso__cache_build_id(struct dso *self, const char *debugdir)
  283. {
  284. bool is_kallsyms = self->kernel && self->long_name[0] != '/';
  285. return build_id_cache__add_b(self->build_id, sizeof(self->build_id),
  286. self->long_name, debugdir, is_kallsyms);
  287. }
  288. static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
  289. {
  290. struct dso *pos;
  291. int err = 0;
  292. dsos__for_each_with_build_id(pos, head)
  293. if (dso__cache_build_id(pos, debugdir))
  294. err = -1;
  295. return err;
  296. }
  297. static int dsos__cache_build_ids(struct perf_header *self)
  298. {
  299. struct perf_session *session = container_of(self,
  300. struct perf_session, header);
  301. struct rb_node *nd;
  302. int ret = 0;
  303. char debugdir[PATH_MAX];
  304. snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
  305. DEBUG_CACHE_DIR);
  306. if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
  307. return -1;
  308. for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) {
  309. struct kernel_info *pos = rb_entry(nd, struct kernel_info,
  310. rb_node);
  311. ret |= __dsos__cache_build_ids(&pos->dsos__kernel, debugdir);
  312. ret |= __dsos__cache_build_ids(&pos->dsos__user, debugdir);
  313. }
  314. return ret ? -1 : 0;
  315. }
  316. static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
  317. {
  318. bool ret = false;
  319. struct perf_session *session = container_of(self,
  320. struct perf_session, header);
  321. struct rb_node *nd;
  322. for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) {
  323. struct kernel_info *pos = rb_entry(nd, struct kernel_info,
  324. rb_node);
  325. ret |= __dsos__read_build_ids(&pos->dsos__kernel, with_hits);
  326. ret |= __dsos__read_build_ids(&pos->dsos__user, with_hits);
  327. }
  328. return ret;
  329. }
  330. static int perf_header__adds_write(struct perf_header *self, int fd)
  331. {
  332. int nr_sections;
  333. struct perf_file_section *feat_sec;
  334. int sec_size;
  335. u64 sec_start;
  336. int idx = 0, err;
  337. if (dsos__read_build_ids(self, true))
  338. perf_header__set_feat(self, HEADER_BUILD_ID);
  339. nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
  340. if (!nr_sections)
  341. return 0;
  342. feat_sec = calloc(sizeof(*feat_sec), nr_sections);
  343. if (feat_sec == NULL)
  344. return -ENOMEM;
  345. sec_size = sizeof(*feat_sec) * nr_sections;
  346. sec_start = self->data_offset + self->data_size;
  347. lseek(fd, sec_start + sec_size, SEEK_SET);
  348. if (perf_header__has_feat(self, HEADER_TRACE_INFO)) {
  349. struct perf_file_section *trace_sec;
  350. trace_sec = &feat_sec[idx++];
  351. /* Write trace info */
  352. trace_sec->offset = lseek(fd, 0, SEEK_CUR);
  353. read_tracing_data(fd, attrs, nr_counters);
  354. trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
  355. }
  356. if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
  357. struct perf_file_section *buildid_sec;
  358. buildid_sec = &feat_sec[idx++];
  359. /* Write build-ids */
  360. buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
  361. err = dsos__write_buildid_table(self, fd);
  362. if (err < 0) {
  363. pr_debug("failed to write buildid table\n");
  364. goto out_free;
  365. }
  366. buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
  367. buildid_sec->offset;
  368. dsos__cache_build_ids(self);
  369. }
  370. lseek(fd, sec_start, SEEK_SET);
  371. err = do_write(fd, feat_sec, sec_size);
  372. if (err < 0)
  373. pr_debug("failed to write feature section\n");
  374. out_free:
  375. free(feat_sec);
  376. return err;
  377. }
  378. int perf_header__write_pipe(int fd)
  379. {
  380. struct perf_pipe_file_header f_header;
  381. int err;
  382. f_header = (struct perf_pipe_file_header){
  383. .magic = PERF_MAGIC,
  384. .size = sizeof(f_header),
  385. };
  386. err = do_write(fd, &f_header, sizeof(f_header));
  387. if (err < 0) {
  388. pr_debug("failed to write perf pipe header\n");
  389. return err;
  390. }
  391. return 0;
  392. }
  393. int perf_header__write(struct perf_header *self, int fd, bool at_exit)
  394. {
  395. struct perf_file_header f_header;
  396. struct perf_file_attr f_attr;
  397. struct perf_header_attr *attr;
  398. int i, err;
  399. lseek(fd, sizeof(f_header), SEEK_SET);
  400. for (i = 0; i < self->attrs; i++) {
  401. attr = self->attr[i];
  402. attr->id_offset = lseek(fd, 0, SEEK_CUR);
  403. err = do_write(fd, attr->id, attr->ids * sizeof(u64));
  404. if (err < 0) {
  405. pr_debug("failed to write perf header\n");
  406. return err;
  407. }
  408. }
  409. self->attr_offset = lseek(fd, 0, SEEK_CUR);
  410. for (i = 0; i < self->attrs; i++) {
  411. attr = self->attr[i];
  412. f_attr = (struct perf_file_attr){
  413. .attr = attr->attr,
  414. .ids = {
  415. .offset = attr->id_offset,
  416. .size = attr->ids * sizeof(u64),
  417. }
  418. };
  419. err = do_write(fd, &f_attr, sizeof(f_attr));
  420. if (err < 0) {
  421. pr_debug("failed to write perf header attribute\n");
  422. return err;
  423. }
  424. }
  425. self->event_offset = lseek(fd, 0, SEEK_CUR);
  426. self->event_size = event_count * sizeof(struct perf_trace_event_type);
  427. if (events) {
  428. err = do_write(fd, events, self->event_size);
  429. if (err < 0) {
  430. pr_debug("failed to write perf header events\n");
  431. return err;
  432. }
  433. }
  434. self->data_offset = lseek(fd, 0, SEEK_CUR);
  435. if (at_exit) {
  436. err = perf_header__adds_write(self, fd);
  437. if (err < 0)
  438. return err;
  439. }
  440. f_header = (struct perf_file_header){
  441. .magic = PERF_MAGIC,
  442. .size = sizeof(f_header),
  443. .attr_size = sizeof(f_attr),
  444. .attrs = {
  445. .offset = self->attr_offset,
  446. .size = self->attrs * sizeof(f_attr),
  447. },
  448. .data = {
  449. .offset = self->data_offset,
  450. .size = self->data_size,
  451. },
  452. .event_types = {
  453. .offset = self->event_offset,
  454. .size = self->event_size,
  455. },
  456. };
  457. memcpy(&f_header.adds_features, &self->adds_features, sizeof(self->adds_features));
  458. lseek(fd, 0, SEEK_SET);
  459. err = do_write(fd, &f_header, sizeof(f_header));
  460. if (err < 0) {
  461. pr_debug("failed to write perf header\n");
  462. return err;
  463. }
  464. lseek(fd, self->data_offset + self->data_size, SEEK_SET);
  465. self->frozen = 1;
  466. return 0;
  467. }
  468. static int perf_header__getbuffer64(struct perf_header *self,
  469. int fd, void *buf, size_t size)
  470. {
  471. if (do_read(fd, buf, size) <= 0)
  472. return -1;
  473. if (self->needs_swap)
  474. mem_bswap_64(buf, size);
  475. return 0;
  476. }
  477. int perf_header__process_sections(struct perf_header *self, int fd,
  478. int (*process)(struct perf_file_section *self,
  479. struct perf_header *ph,
  480. int feat, int fd))
  481. {
  482. struct perf_file_section *feat_sec;
  483. int nr_sections;
  484. int sec_size;
  485. int idx = 0;
  486. int err = -1, feat = 1;
  487. nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
  488. if (!nr_sections)
  489. return 0;
  490. feat_sec = calloc(sizeof(*feat_sec), nr_sections);
  491. if (!feat_sec)
  492. return -1;
  493. sec_size = sizeof(*feat_sec) * nr_sections;
  494. lseek(fd, self->data_offset + self->data_size, SEEK_SET);
  495. if (perf_header__getbuffer64(self, fd, feat_sec, sec_size))
  496. goto out_free;
  497. err = 0;
  498. while (idx < nr_sections && feat < HEADER_LAST_FEATURE) {
  499. if (perf_header__has_feat(self, feat)) {
  500. struct perf_file_section *sec = &feat_sec[idx++];
  501. err = process(sec, self, feat, fd);
  502. if (err < 0)
  503. break;
  504. }
  505. ++feat;
  506. }
  507. out_free:
  508. free(feat_sec);
  509. return err;
  510. }
  511. int perf_file_header__read(struct perf_file_header *self,
  512. struct perf_header *ph, int fd)
  513. {
  514. lseek(fd, 0, SEEK_SET);
  515. if (do_read(fd, self, sizeof(*self)) <= 0 ||
  516. memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
  517. return -1;
  518. if (self->attr_size != sizeof(struct perf_file_attr)) {
  519. u64 attr_size = bswap_64(self->attr_size);
  520. if (attr_size != sizeof(struct perf_file_attr))
  521. return -1;
  522. mem_bswap_64(self, offsetof(struct perf_file_header,
  523. adds_features));
  524. ph->needs_swap = true;
  525. }
  526. if (self->size != sizeof(*self)) {
  527. /* Support the previous format */
  528. if (self->size == offsetof(typeof(*self), adds_features))
  529. bitmap_zero(self->adds_features, HEADER_FEAT_BITS);
  530. else
  531. return -1;
  532. }
  533. memcpy(&ph->adds_features, &self->adds_features,
  534. sizeof(ph->adds_features));
  535. /*
  536. * FIXME: hack that assumes that if we need swap the perf.data file
  537. * may be coming from an arch with a different word-size, ergo different
  538. * DEFINE_BITMAP format, investigate more later, but for now its mostly
  539. * safe to assume that we have a build-id section. Trace files probably
  540. * have several other issues in this realm anyway...
  541. */
  542. if (ph->needs_swap) {
  543. memset(&ph->adds_features, 0, sizeof(ph->adds_features));
  544. perf_header__set_feat(ph, HEADER_BUILD_ID);
  545. }
  546. ph->event_offset = self->event_types.offset;
  547. ph->event_size = self->event_types.size;
  548. ph->data_offset = self->data.offset;
  549. ph->data_size = self->data.size;
  550. return 0;
  551. }
  552. static int __event_process_build_id(struct build_id_event *bev,
  553. char *filename,
  554. struct perf_session *session)
  555. {
  556. int err = -1;
  557. struct list_head *head;
  558. struct kernel_info *kerninfo;
  559. u16 misc;
  560. struct dso *dso;
  561. enum dso_kernel_type dso_type;
  562. kerninfo = kerninfo__findnew(&session->kerninfo_root, bev->pid);
  563. if (!kerninfo)
  564. goto out;
  565. misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
  566. switch (misc) {
  567. case PERF_RECORD_MISC_KERNEL:
  568. dso_type = DSO_TYPE_KERNEL;
  569. head = &kerninfo->dsos__kernel;
  570. break;
  571. case PERF_RECORD_MISC_GUEST_KERNEL:
  572. dso_type = DSO_TYPE_GUEST_KERNEL;
  573. head = &kerninfo->dsos__kernel;
  574. break;
  575. case PERF_RECORD_MISC_USER:
  576. case PERF_RECORD_MISC_GUEST_USER:
  577. dso_type = DSO_TYPE_USER;
  578. head = &kerninfo->dsos__user;
  579. break;
  580. default:
  581. goto out;
  582. }
  583. dso = __dsos__findnew(head, filename);
  584. if (dso != NULL) {
  585. dso__set_build_id(dso, &bev->build_id);
  586. if (filename[0] == '[')
  587. dso->kernel = dso_type;
  588. }
  589. err = 0;
  590. out:
  591. return err;
  592. }
  593. static int perf_header__read_build_ids(struct perf_header *self,
  594. int input, u64 offset, u64 size)
  595. {
  596. struct perf_session *session = container_of(self,
  597. struct perf_session, header);
  598. struct build_id_event bev;
  599. char filename[PATH_MAX];
  600. u64 limit = offset + size;
  601. int err = -1;
  602. while (offset < limit) {
  603. ssize_t len;
  604. if (read(input, &bev, sizeof(bev)) != sizeof(bev))
  605. goto out;
  606. if (self->needs_swap)
  607. perf_event_header__bswap(&bev.header);
  608. len = bev.header.size - sizeof(bev);
  609. if (read(input, filename, len) != len)
  610. goto out;
  611. __event_process_build_id(&bev, filename, session);
  612. offset += bev.header.size;
  613. }
  614. err = 0;
  615. out:
  616. return err;
  617. }
  618. static int perf_file_section__process(struct perf_file_section *self,
  619. struct perf_header *ph,
  620. int feat, int fd)
  621. {
  622. if (lseek(fd, self->offset, SEEK_SET) == (off_t)-1) {
  623. pr_debug("Failed to lseek to %Ld offset for feature %d, "
  624. "continuing...\n", self->offset, feat);
  625. return 0;
  626. }
  627. switch (feat) {
  628. case HEADER_TRACE_INFO:
  629. trace_report(fd);
  630. break;
  631. case HEADER_BUILD_ID:
  632. if (perf_header__read_build_ids(ph, fd, self->offset, self->size))
  633. pr_debug("Failed to read buildids, continuing...\n");
  634. break;
  635. default:
  636. pr_debug("unknown feature %d, continuing...\n", feat);
  637. }
  638. return 0;
  639. }
  640. static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
  641. struct perf_header *ph, int fd)
  642. {
  643. if (do_read(fd, self, sizeof(*self)) <= 0 ||
  644. memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
  645. return -1;
  646. if (self->size != sizeof(*self)) {
  647. u64 size = bswap_64(self->size);
  648. if (size != sizeof(*self))
  649. return -1;
  650. ph->needs_swap = true;
  651. }
  652. return 0;
  653. }
  654. static int perf_header__read_pipe(struct perf_session *session, int fd)
  655. {
  656. struct perf_header *self = &session->header;
  657. struct perf_pipe_file_header f_header;
  658. if (perf_file_header__read_pipe(&f_header, self, fd) < 0) {
  659. pr_debug("incompatible file format\n");
  660. return -EINVAL;
  661. }
  662. session->fd = fd;
  663. return 0;
  664. }
  665. int perf_header__read(struct perf_session *session, int fd)
  666. {
  667. struct perf_header *self = &session->header;
  668. struct perf_file_header f_header;
  669. struct perf_file_attr f_attr;
  670. u64 f_id;
  671. int nr_attrs, nr_ids, i, j;
  672. if (session->fd_pipe)
  673. return perf_header__read_pipe(session, fd);
  674. if (perf_file_header__read(&f_header, self, fd) < 0) {
  675. pr_debug("incompatible file format\n");
  676. return -EINVAL;
  677. }
  678. nr_attrs = f_header.attrs.size / sizeof(f_attr);
  679. lseek(fd, f_header.attrs.offset, SEEK_SET);
  680. for (i = 0; i < nr_attrs; i++) {
  681. struct perf_header_attr *attr;
  682. off_t tmp;
  683. if (perf_header__getbuffer64(self, fd, &f_attr, sizeof(f_attr)))
  684. goto out_errno;
  685. tmp = lseek(fd, 0, SEEK_CUR);
  686. attr = perf_header_attr__new(&f_attr.attr);
  687. if (attr == NULL)
  688. return -ENOMEM;
  689. nr_ids = f_attr.ids.size / sizeof(u64);
  690. lseek(fd, f_attr.ids.offset, SEEK_SET);
  691. for (j = 0; j < nr_ids; j++) {
  692. if (perf_header__getbuffer64(self, fd, &f_id, sizeof(f_id)))
  693. goto out_errno;
  694. if (perf_header_attr__add_id(attr, f_id) < 0) {
  695. perf_header_attr__delete(attr);
  696. return -ENOMEM;
  697. }
  698. }
  699. if (perf_header__add_attr(self, attr) < 0) {
  700. perf_header_attr__delete(attr);
  701. return -ENOMEM;
  702. }
  703. lseek(fd, tmp, SEEK_SET);
  704. }
  705. if (f_header.event_types.size) {
  706. lseek(fd, f_header.event_types.offset, SEEK_SET);
  707. events = malloc(f_header.event_types.size);
  708. if (events == NULL)
  709. return -ENOMEM;
  710. if (perf_header__getbuffer64(self, fd, events,
  711. f_header.event_types.size))
  712. goto out_errno;
  713. event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
  714. }
  715. perf_header__process_sections(self, fd, perf_file_section__process);
  716. lseek(fd, self->data_offset, SEEK_SET);
  717. self->frozen = 1;
  718. return 0;
  719. out_errno:
  720. return -errno;
  721. }
  722. u64 perf_header__sample_type(struct perf_header *header)
  723. {
  724. u64 type = 0;
  725. int i;
  726. for (i = 0; i < header->attrs; i++) {
  727. struct perf_header_attr *attr = header->attr[i];
  728. if (!type)
  729. type = attr->attr.sample_type;
  730. else if (type != attr->attr.sample_type)
  731. die("non matching sample_type");
  732. }
  733. return type;
  734. }
  735. struct perf_event_attr *
  736. perf_header__find_attr(u64 id, struct perf_header *header)
  737. {
  738. int i;
  739. for (i = 0; i < header->attrs; i++) {
  740. struct perf_header_attr *attr = header->attr[i];
  741. int j;
  742. for (j = 0; j < attr->ids; j++) {
  743. if (attr->id[j] == id)
  744. return &attr->attr;
  745. }
  746. }
  747. return NULL;
  748. }
  749. int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
  750. event__handler_t process,
  751. struct perf_session *session)
  752. {
  753. event_t *ev;
  754. size_t size;
  755. int err;
  756. size = sizeof(struct perf_event_attr);
  757. size = ALIGN(size, sizeof(u64));
  758. size += sizeof(struct perf_event_header);
  759. size += ids * sizeof(u64);
  760. ev = malloc(size);
  761. ev->attr.attr = *attr;
  762. memcpy(ev->attr.id, id, ids * sizeof(u64));
  763. ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
  764. ev->attr.header.size = size;
  765. err = process(ev, session);
  766. free(ev);
  767. return err;
  768. }
  769. int event__synthesize_attrs(struct perf_header *self,
  770. event__handler_t process,
  771. struct perf_session *session)
  772. {
  773. struct perf_header_attr *attr;
  774. int i, err = 0;
  775. for (i = 0; i < self->attrs; i++) {
  776. attr = self->attr[i];
  777. err = event__synthesize_attr(&attr->attr, attr->ids, attr->id,
  778. process, session);
  779. if (err) {
  780. pr_debug("failed to create perf header attribute\n");
  781. return err;
  782. }
  783. }
  784. return err;
  785. }
  786. int event__process_attr(event_t *self, struct perf_session *session)
  787. {
  788. struct perf_header_attr *attr;
  789. unsigned int i, ids, n_ids;
  790. attr = perf_header_attr__new(&self->attr.attr);
  791. if (attr == NULL)
  792. return -ENOMEM;
  793. ids = self->header.size;
  794. ids -= (void *)&self->attr.id - (void *)self;
  795. n_ids = ids / sizeof(u64);
  796. for (i = 0; i < n_ids; i++) {
  797. if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) {
  798. perf_header_attr__delete(attr);
  799. return -ENOMEM;
  800. }
  801. }
  802. if (perf_header__add_attr(&session->header, attr) < 0) {
  803. perf_header_attr__delete(attr);
  804. return -ENOMEM;
  805. }
  806. perf_session__update_sample_type(session);
  807. return 0;
  808. }
  809. int event__synthesize_event_type(u64 event_id, char *name,
  810. event__handler_t process,
  811. struct perf_session *session)
  812. {
  813. event_t ev;
  814. size_t size = 0;
  815. int err = 0;
  816. memset(&ev, 0, sizeof(ev));
  817. ev.event_type.event_type.event_id = event_id;
  818. memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
  819. strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
  820. ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
  821. size = strlen(name);
  822. size = ALIGN(size, sizeof(u64));
  823. ev.event_type.header.size = sizeof(ev.event_type) -
  824. (sizeof(ev.event_type.event_type.name) - size);
  825. err = process(&ev, session);
  826. return err;
  827. }
  828. int event__synthesize_event_types(event__handler_t process,
  829. struct perf_session *session)
  830. {
  831. struct perf_trace_event_type *type;
  832. int i, err = 0;
  833. for (i = 0; i < event_count; i++) {
  834. type = &events[i];
  835. err = event__synthesize_event_type(type->event_id, type->name,
  836. process, session);
  837. if (err) {
  838. pr_debug("failed to create perf header event type\n");
  839. return err;
  840. }
  841. }
  842. return err;
  843. }
  844. int event__process_event_type(event_t *self,
  845. struct perf_session *session __unused)
  846. {
  847. if (perf_header__push_event(self->event_type.event_type.event_id,
  848. self->event_type.event_type.name) < 0)
  849. return -ENOMEM;
  850. return 0;
  851. }
  852. int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
  853. int nb_events,
  854. event__handler_t process,
  855. struct perf_session *session __unused)
  856. {
  857. event_t ev;
  858. ssize_t size = 0, aligned_size = 0, padding;
  859. int err = 0;
  860. memset(&ev, 0, sizeof(ev));
  861. ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
  862. size = read_tracing_data_size(fd, pattrs, nb_events);
  863. if (size <= 0)
  864. return size;
  865. aligned_size = ALIGN(size, sizeof(u64));
  866. padding = aligned_size - size;
  867. ev.tracing_data.header.size = sizeof(ev.tracing_data);
  868. ev.tracing_data.size = aligned_size;
  869. process(&ev, session);
  870. err = read_tracing_data(fd, pattrs, nb_events);
  871. write_padded(fd, NULL, 0, padding);
  872. return aligned_size;
  873. }
  874. int event__process_tracing_data(event_t *self,
  875. struct perf_session *session)
  876. {
  877. ssize_t size_read, padding, size = self->tracing_data.size;
  878. off_t offset = lseek(session->fd, 0, SEEK_CUR);
  879. char buf[BUFSIZ];
  880. /* setup for reading amidst mmap */
  881. lseek(session->fd, offset + sizeof(struct tracing_data_event),
  882. SEEK_SET);
  883. size_read = trace_report(session->fd);
  884. padding = ALIGN(size_read, sizeof(u64)) - size_read;
  885. if (read(session->fd, buf, padding) < 0)
  886. die("reading input file");
  887. if (size_read + padding != size)
  888. die("tracing data size mismatch");
  889. return size_read + padding;
  890. }
  891. int event__synthesize_build_id(struct dso *pos, u16 misc,
  892. event__handler_t process,
  893. struct kernel_info *kerninfo,
  894. struct perf_session *session)
  895. {
  896. event_t ev;
  897. size_t len;
  898. int err = 0;
  899. if (!pos->hit)
  900. return err;
  901. memset(&ev, 0, sizeof(ev));
  902. len = pos->long_name_len + 1;
  903. len = ALIGN(len, NAME_ALIGN);
  904. memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
  905. ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
  906. ev.build_id.header.misc = misc;
  907. ev.build_id.pid = kerninfo->pid;
  908. ev.build_id.header.size = sizeof(ev.build_id) + len;
  909. memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
  910. err = process(&ev, session);
  911. return err;
  912. }
  913. static int __event_synthesize_build_ids(struct list_head *head, u16 misc,
  914. event__handler_t process,
  915. struct kernel_info *kerninfo,
  916. struct perf_session *session)
  917. {
  918. struct dso *pos;
  919. dsos__for_each_with_build_id(pos, head) {
  920. int err;
  921. if (!pos->hit)
  922. continue;
  923. err = event__synthesize_build_id(pos, misc, process,
  924. kerninfo, session);
  925. if (err < 0)
  926. return err;
  927. }
  928. return 0;
  929. }
  930. int event__synthesize_build_ids(event__handler_t process,
  931. struct perf_session *session)
  932. {
  933. int err = 0;
  934. u16 kmisc, umisc;
  935. struct kernel_info *pos;
  936. struct rb_node *nd;
  937. if (!dsos__read_build_ids(&session->header, true))
  938. return 0;
  939. for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) {
  940. pos = rb_entry(nd, struct kernel_info, rb_node);
  941. if (is_host_kernel(pos)) {
  942. kmisc = PERF_RECORD_MISC_KERNEL;
  943. umisc = PERF_RECORD_MISC_USER;
  944. } else {
  945. kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
  946. umisc = PERF_RECORD_MISC_GUEST_USER;
  947. }
  948. err = __event_synthesize_build_ids(&pos->dsos__kernel,
  949. kmisc, process, pos, session);
  950. if (err == 0)
  951. err = __event_synthesize_build_ids(&pos->dsos__user,
  952. umisc, process, pos, session);
  953. if (err)
  954. break;
  955. }
  956. if (err < 0) {
  957. pr_debug("failed to synthesize build ids\n");
  958. return err;
  959. }
  960. dsos__cache_build_ids(&session->header);
  961. return 0;
  962. }
  963. int event__process_build_id(event_t *self,
  964. struct perf_session *session)
  965. {
  966. __event_process_build_id(&self->build_id,
  967. self->build_id.filename,
  968. session);
  969. return 0;
  970. }