@@ -107,6 +107,7 @@ enum build_id_rewrite_style {
107107 BID_RWS__NONE = 0 ,
108108 BID_RWS__INJECT_HEADER_LAZY ,
109109 BID_RWS__INJECT_HEADER_ALL ,
110+ BID_RWS__MMAP2_BUILDID_ALL ,
110111};
111112
112113struct perf_inject {
@@ -146,6 +147,16 @@ static int tool__inject_build_id(const struct perf_tool *tool,
146147 __u16 misc ,
147148 const char * filename ,
148149 struct dso * dso , u32 flags );
150+ static int tool__inject_mmap2_build_id (const struct perf_tool * tool ,
151+ struct perf_sample * sample ,
152+ struct machine * machine ,
153+ const struct evsel * evsel ,
154+ __u16 misc ,
155+ __u32 pid , __u32 tid ,
156+ __u64 start , __u64 len , __u64 pgoff ,
157+ struct dso * dso ,
158+ __u32 prot , __u32 flags ,
159+ const char * filename );
149160
150161static int output_bytes (struct perf_inject * inject , void * buf , size_t sz )
151162{
@@ -161,6 +172,7 @@ static int output_bytes(struct perf_inject *inject, void *buf, size_t sz)
161172
162173static int perf_event__repipe_synth (const struct perf_tool * tool ,
163174 union perf_event * event )
175+
164176{
165177 struct perf_inject * inject = container_of (tool , struct perf_inject ,
166178 tool );
@@ -454,7 +466,9 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
454466 union perf_event * event ,
455467 struct perf_sample * sample ,
456468 struct machine * machine ,
457- __u32 pid , __u32 tid , __u32 flags ,
469+ __u32 pid , __u32 tid ,
470+ __u64 start , __u64 len , __u64 pgoff ,
471+ __u32 flags , __u32 prot ,
458472 const char * filename ,
459473 const struct dso_id * dso_id ,
460474 int (* perf_event_process )(const struct perf_tool * tool ,
@@ -525,6 +539,26 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
525539 return err ;
526540 }
527541 }
542+ if ((inject -> build_id_style == BID_RWS__MMAP2_BUILDID_ALL ) &&
543+ !(event -> header .misc & PERF_RECORD_MISC_MMAP_BUILD_ID )) {
544+ struct evsel * evsel = evlist__event2evsel (inject -> session -> evlist , event );
545+
546+ if (evsel && !dso_sought ) {
547+ dso = findnew_dso (pid , tid , filename , dso_id , machine );
548+ dso_sought = true;
549+ }
550+ if (evsel && dso &&
551+ !tool__inject_mmap2_build_id (tool , sample , machine , evsel ,
552+ sample -> cpumode | PERF_RECORD_MISC_MMAP_BUILD_ID ,
553+ pid , tid , start , len , pgoff ,
554+ dso ,
555+ prot , flags ,
556+ filename )) {
557+ /* Injected mmap2 so no need to repipe. */
558+ dso__put (dso );
559+ return 0 ;
560+ }
561+ }
528562 dso__put (dso );
529563 return perf_event__repipe (tool , event , sample , machine );
530564}
@@ -536,7 +570,9 @@ static int perf_event__repipe_mmap(const struct perf_tool *tool,
536570{
537571 return perf_event__repipe_common_mmap (
538572 tool , event , sample , machine ,
539- event -> mmap .pid , event -> mmap .tid , /*flags=*/ 0 ,
573+ event -> mmap .pid , event -> mmap .tid ,
574+ event -> mmap .start , event -> mmap .len , event -> mmap .pgoff ,
575+ /*flags=*/ 0 , PROT_EXEC ,
540576 event -> mmap .filename , /*dso_id=*/ NULL ,
541577 perf_event__process_mmap );
542578}
@@ -559,7 +595,9 @@ static int perf_event__repipe_mmap2(const struct perf_tool *tool,
559595
560596 return perf_event__repipe_common_mmap (
561597 tool , event , sample , machine ,
562- event -> mmap2 .pid , event -> mmap2 .tid , event -> mmap2 .flags ,
598+ event -> mmap2 .pid , event -> mmap2 .tid ,
599+ event -> mmap2 .start , event -> mmap2 .len , event -> mmap2 .pgoff ,
600+ event -> mmap2 .flags , event -> mmap2 .prot ,
563601 event -> mmap2 .filename , dso_id ,
564602 perf_event__process_mmap2 );
565603}
@@ -748,6 +786,45 @@ static int tool__inject_build_id(const struct perf_tool *tool,
748786 return 0 ;
749787}
750788
789+ static int tool__inject_mmap2_build_id (const struct perf_tool * tool ,
790+ struct perf_sample * sample ,
791+ struct machine * machine ,
792+ const struct evsel * evsel ,
793+ __u16 misc ,
794+ __u32 pid , __u32 tid ,
795+ __u64 start , __u64 len , __u64 pgoff ,
796+ struct dso * dso ,
797+ __u32 prot , __u32 flags ,
798+ const char * filename )
799+ {
800+ int err ;
801+
802+ /* Return to repipe anonymous maps. */
803+ if (is_anon_memory (filename ) || flags & MAP_HUGETLB )
804+ return 1 ;
805+ if (is_no_dso_memory (filename ))
806+ return 1 ;
807+
808+ if (dso__read_build_id (dso )) {
809+ pr_debug ("no build_id found for %s\n" , filename );
810+ return -1 ;
811+ }
812+
813+ err = perf_event__synthesize_mmap2_build_id (tool , sample , machine ,
814+ perf_event__repipe ,
815+ evsel ,
816+ misc , pid , tid ,
817+ start , len , pgoff ,
818+ dso__bid (dso ),
819+ prot , flags ,
820+ filename );
821+ if (err ) {
822+ pr_err ("Can't synthesize build_id event for %s\n" , filename );
823+ return -1 ;
824+ }
825+ return 0 ;
826+ }
827+
751828static int mark_dso_hit (const struct perf_tool * tool ,
752829 struct perf_sample * sample ,
753830 struct machine * machine ,
@@ -2261,12 +2338,15 @@ int cmd_inject(int argc, const char **argv)
22612338 const char * known_build_ids = NULL ;
22622339 bool build_ids ;
22632340 bool build_id_all ;
2341+ bool mmap2_build_id_all ;
22642342
22652343 struct option options [] = {
22662344 OPT_BOOLEAN ('b' , "build-ids" , & build_ids ,
22672345 "Inject build-ids into the output stream" ),
22682346 OPT_BOOLEAN (0 , "buildid-all" , & build_id_all ,
22692347 "Inject build-ids of all DSOs into the output stream" ),
2348+ OPT_BOOLEAN (0 , "mmap2-buildid-all" , & mmap2_build_id_all ,
2349+ "Rewrite all mmap events as mmap2 events with build IDs" ),
22702350 OPT_STRING (0 , "known-build-ids" , & known_build_ids ,
22712351 "buildid path [,buildid path...]" ,
22722352 "build-ids to use for given paths" ),
@@ -2363,6 +2443,8 @@ int cmd_inject(int argc, const char **argv)
23632443 return -1 ;
23642444 }
23652445 }
2446+ if (mmap2_build_id_all )
2447+ inject .build_id_style = BID_RWS__MMAP2_BUILDID_ALL ;
23662448 if (build_ids )
23672449 inject .build_id_style = BID_RWS__INJECT_HEADER_LAZY ;
23682450 if (build_id_all )
0 commit comments