@@ -108,6 +108,7 @@ enum build_id_rewrite_style {
108108 BID_RWS__INJECT_HEADER_LAZY ,
109109 BID_RWS__INJECT_HEADER_ALL ,
110110 BID_RWS__MMAP2_BUILDID_ALL ,
111+ BID_RWS__MMAP2_BUILDID_LAZY ,
111112};
112113
113114struct perf_inject {
@@ -527,7 +528,8 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
527528 * Remember the evsel for lazy build id generation. It is used
528529 * for the sample id header type.
529530 */
530- if (inject -> build_id_style == BID_RWS__INJECT_HEADER_LAZY &&
531+ if ((inject -> build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
532+ inject -> build_id_style == BID_RWS__MMAP2_BUILDID_LAZY ) &&
531533 !inject -> mmap_evsel )
532534 inject -> mmap_evsel = evlist__event2evsel (inject -> session -> evlist , event );
533535
@@ -560,6 +562,9 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
560562 }
561563 }
562564 dso__put (dso );
565+ if (inject -> build_id_style == BID_RWS__MMAP2_BUILDID_LAZY )
566+ return 0 ;
567+
563568 return perf_event__repipe (tool , event , sample , machine );
564569}
565570
@@ -825,7 +830,8 @@ static int tool__inject_mmap2_build_id(const struct perf_tool *tool,
825830 return 0 ;
826831}
827832
828- static int mark_dso_hit (const struct perf_tool * tool ,
833+ static int mark_dso_hit (const struct perf_inject * inject ,
834+ const struct perf_tool * tool ,
829835 struct perf_sample * sample ,
830836 struct machine * machine ,
831837 const struct evsel * mmap_evsel ,
@@ -854,16 +860,39 @@ static int mark_dso_hit(const struct perf_tool *tool,
854860 }
855861 }
856862 dso = map__dso (map );
857- if (dso && !dso__hit (dso )) {
858- dso__set_hit (dso );
859- tool__inject_build_id (tool , sample , machine ,
860- mmap_evsel , misc , dso__long_name (dso ), dso ,
861- map__flags (map ));
863+ if (inject -> build_id_style == BID_RWS__INJECT_HEADER_LAZY ) {
864+ if (dso && !dso__hit (dso )) {
865+ dso__set_hit (dso );
866+ tool__inject_build_id (tool , sample , machine ,
867+ mmap_evsel , misc , dso__long_name (dso ), dso ,
868+ map__flags (map ));
869+ }
870+ } else if (inject -> build_id_style == BID_RWS__MMAP2_BUILDID_LAZY ) {
871+ if (!map__hit (map )) {
872+ const struct build_id null_bid = { .size = 0 };
873+ const struct build_id * bid = dso ? dso__bid (dso ) : & null_bid ;
874+ const char * filename = dso ? dso__long_name (dso ) : "" ;
875+
876+ map__set_hit (map );
877+ perf_event__synthesize_mmap2_build_id (tool , sample , machine ,
878+ perf_event__repipe ,
879+ mmap_evsel ,
880+ misc ,
881+ sample -> pid , sample -> tid ,
882+ map__start (map ),
883+ map__end (map ) - map__start (map ),
884+ map__pgoff (map ),
885+ bid ,
886+ map__prot (map ),
887+ map__flags (map ),
888+ filename );
889+ }
862890 }
863891 return 0 ;
864892}
865893
866894struct mark_dso_hit_args {
895+ const struct perf_inject * inject ;
867896 const struct perf_tool * tool ;
868897 struct perf_sample * sample ;
869898 struct machine * machine ;
@@ -875,7 +904,7 @@ static int mark_dso_hit_callback(struct callchain_cursor_node *node, void *data)
875904 struct mark_dso_hit_args * args = data ;
876905 struct map * map = node -> ms .map ;
877906
878- return mark_dso_hit (args -> tool , args -> sample , args -> machine ,
907+ return mark_dso_hit (args -> inject , args -> tool , args -> sample , args -> machine ,
879908 args -> mmap_evsel , map , /*sample_in_dso=*/ false);
880909}
881910
@@ -888,6 +917,7 @@ int perf_event__inject_buildid(const struct perf_tool *tool, union perf_event *e
888917 struct thread * thread ;
889918 struct perf_inject * inject = container_of (tool , struct perf_inject , tool );
890919 struct mark_dso_hit_args args = {
920+ .inject = inject ,
891921 .tool = tool ,
892922 /*
893923 * Use the parsed sample data of the sample event, which will
@@ -907,7 +937,7 @@ int perf_event__inject_buildid(const struct perf_tool *tool, union perf_event *e
907937 }
908938
909939 if (thread__find_map (thread , sample -> cpumode , sample -> ip , & al )) {
910- mark_dso_hit (tool , sample , machine , args .mmap_evsel , al .map ,
940+ mark_dso_hit (inject , tool , sample , machine , args .mmap_evsel , al .map ,
911941 /*sample_in_dso=*/ true);
912942 }
913943
@@ -2155,7 +2185,8 @@ static int __cmd_inject(struct perf_inject *inject)
21552185#endif
21562186 }
21572187
2158- if (inject -> build_id_style == BID_RWS__INJECT_HEADER_LAZY ) {
2188+ if (inject -> build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
2189+ inject -> build_id_style == BID_RWS__MMAP2_BUILDID_LAZY ) {
21592190 inject -> tool .sample = perf_event__inject_buildid ;
21602191 } else if (inject -> sched_stat ) {
21612192 struct evsel * evsel ;
@@ -2338,13 +2369,16 @@ int cmd_inject(int argc, const char **argv)
23382369 const char * known_build_ids = NULL ;
23392370 bool build_ids ;
23402371 bool build_id_all ;
2372+ bool mmap2_build_ids ;
23412373 bool mmap2_build_id_all ;
23422374
23432375 struct option options [] = {
23442376 OPT_BOOLEAN ('b' , "build-ids" , & build_ids ,
23452377 "Inject build-ids into the output stream" ),
23462378 OPT_BOOLEAN (0 , "buildid-all" , & build_id_all ,
23472379 "Inject build-ids of all DSOs into the output stream" ),
2380+ OPT_BOOLEAN ('B' , "mmap2-buildids" , & mmap2_build_ids ,
2381+ "Drop unused mmap events, make others mmap2 with build IDs" ),
23482382 OPT_BOOLEAN (0 , "mmap2-buildid-all" , & mmap2_build_id_all ,
23492383 "Rewrite all mmap events as mmap2 events with build IDs" ),
23502384 OPT_STRING (0 , "known-build-ids" , & known_build_ids ,
@@ -2443,6 +2477,8 @@ int cmd_inject(int argc, const char **argv)
24432477 return -1 ;
24442478 }
24452479 }
2480+ if (mmap2_build_ids )
2481+ inject .build_id_style = BID_RWS__MMAP2_BUILDID_LAZY ;
24462482 if (mmap2_build_id_all )
24472483 inject .build_id_style = BID_RWS__MMAP2_BUILDID_ALL ;
24482484 if (build_ids )
@@ -2453,7 +2489,8 @@ int cmd_inject(int argc, const char **argv)
24532489 data .path = inject .input_name ;
24542490
24552491 ordered_events = inject .jit_mode || inject .sched_stat ||
2456- (inject .build_id_style == BID_RWS__INJECT_HEADER_LAZY );
2492+ inject .build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
2493+ inject .build_id_style == BID_RWS__MMAP2_BUILDID_LAZY ;
24572494 perf_tool__init (& inject .tool , ordered_events );
24582495 inject .tool .sample = perf_event__repipe_sample ;
24592496 inject .tool .read = perf_event__repipe_sample ;
@@ -2532,7 +2569,8 @@ int cmd_inject(int argc, const char **argv)
25322569 }
25332570 }
25342571
2535- if (inject .build_id_style == BID_RWS__INJECT_HEADER_LAZY ) {
2572+ if (inject .build_id_style == BID_RWS__INJECT_HEADER_LAZY ||
2573+ inject .build_id_style == BID_RWS__MMAP2_BUILDID_LAZY ) {
25362574 /*
25372575 * to make sure the mmap records are ordered correctly
25382576 * and so that the correct especially due to jitted code
0 commit comments