@@ -77,6 +77,7 @@ typedef struct lprofFilename {
77
77
char Hostname [COMPILER_RT_MAX_HOSTLEN ];
78
78
unsigned NumPids ;
79
79
unsigned NumHosts ;
80
+ unsigned NumBinaryIds ;
80
81
/* When in-process merging is enabled, this parameter specifies
81
82
* the total number of profile data files shared by all the processes
82
83
* spawned from the same binary. By default the value is 1. If merging
@@ -88,8 +89,8 @@ typedef struct lprofFilename {
88
89
ProfileNameSpecifier PNS ;
89
90
} lprofFilename ;
90
91
91
- static lprofFilename lprofCurFilename = {0 , 0 , 0 , {0 }, NULL ,
92
- { 0 } , 0 , 0 , 0 , PNS_unknown };
92
+ static lprofFilename lprofCurFilename = {0 , 0 , 0 , {0 }, NULL , { 0 } ,
93
+ 0 , 0 , 0 , 0 , PNS_unknown };
93
94
94
95
static int ProfileMergeRequested = 0 ;
95
96
static int getProfileFileSizeForMerging (FILE * ProfileFile ,
@@ -790,7 +791,7 @@ static int checkBounds(int Idx, int Strlen) {
790
791
* lprofcurFilename structure. */
791
792
static int parseFilenamePattern (const char * FilenamePat ,
792
793
unsigned CopyFilenamePat ) {
793
- int NumPids = 0 , NumHosts = 0 , I ;
794
+ int NumPids = 0 , NumHosts = 0 , NumBinaryIds = 0 , I ;
794
795
char * PidChars = & lprofCurFilename .PidChars [0 ];
795
796
char * Hostname = & lprofCurFilename .Hostname [0 ];
796
797
int MergingEnabled = 0 ;
@@ -855,6 +856,16 @@ static int parseFilenamePattern(const char *FilenamePat,
855
856
FilenamePat );
856
857
return -1 ;
857
858
}
859
+ } else if (FilenamePat [I ] == 'b' ) {
860
+ if (!NumBinaryIds ++ ) {
861
+ /* Check if binary ID does not exist or if its size is 0. */
862
+ if (__llvm_write_binary_ids (NULL ) <= 0 ) {
863
+ PROF_WARN ("Unable to get binary ID for filename pattern %s. Using "
864
+ "the default name." ,
865
+ FilenamePat );
866
+ return -1 ;
867
+ }
868
+ }
858
869
} else if (FilenamePat [I ] == 'c' ) {
859
870
if (__llvm_profile_is_continuous_mode_enabled ()) {
860
871
PROF_WARN ("%%c specifier can only be specified once in %s.\n" ,
@@ -887,6 +898,7 @@ static int parseFilenamePattern(const char *FilenamePat,
887
898
888
899
lprofCurFilename .NumPids = NumPids ;
889
900
lprofCurFilename .NumHosts = NumHosts ;
901
+ lprofCurFilename .NumBinaryIds = NumBinaryIds ;
890
902
return 0 ;
891
903
}
892
904
@@ -934,24 +946,53 @@ static void parseAndSetFilename(const char *FilenamePat,
934
946
* filename with PID and hostname substitutions. */
935
947
/* The length to hold uint64_t followed by 3 digits pool id including '_' */
936
948
#define SIGLEN 24
949
+ /* The length to hold 160-bit hash in hexadecimal form */
950
+ #define BINARY_ID_LEN 40
937
951
static int getCurFilenameLength (void ) {
938
952
int Len ;
939
953
if (!lprofCurFilename .FilenamePat || !lprofCurFilename .FilenamePat [0 ])
940
954
return 0 ;
941
955
942
956
if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
943
- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ))
957
+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
958
+ lprofCurFilename .MergePoolSize ))
944
959
return strlen (lprofCurFilename .FilenamePat );
945
960
946
961
Len = strlen (lprofCurFilename .FilenamePat ) +
947
962
lprofCurFilename .NumPids * (strlen (lprofCurFilename .PidChars ) - 2 ) +
948
963
lprofCurFilename .NumHosts * (strlen (lprofCurFilename .Hostname ) - 2 ) +
964
+ lprofCurFilename .NumBinaryIds * BINARY_ID_LEN +
949
965
(lprofCurFilename .TmpDir ? (strlen (lprofCurFilename .TmpDir ) - 1 ) : 0 );
950
966
if (lprofCurFilename .MergePoolSize )
951
967
Len += SIGLEN ;
952
968
return Len ;
953
969
}
954
970
971
+ typedef struct lprofBinaryIdsBuffer {
972
+ char String [BINARY_ID_LEN + 1 ];
973
+ int Length ;
974
+ } lprofBinaryIdsBuffer ;
975
+
976
+ /* Reads binary ID length and then its data, writes it into lprofBinaryIdsBuffer
977
+ * in hexadecimal form. */
978
+ static uint32_t binaryIdsStringWriter (ProfDataWriter * This ,
979
+ ProfDataIOVec * IOVecs ,
980
+ uint32_t NumIOVecs ) {
981
+ if (NumIOVecs < 2 || IOVecs [0 ].ElmSize != sizeof (uint64_t ))
982
+ return -1 ;
983
+ uint64_t BinaryIdLen = * (const uint64_t * )IOVecs [0 ].Data ;
984
+ if (IOVecs [1 ].ElmSize != sizeof (uint8_t ) || IOVecs [1 ].NumElm != BinaryIdLen )
985
+ return -1 ;
986
+ const uint8_t * BinaryIdData = (const uint8_t * )IOVecs [1 ].Data ;
987
+ lprofBinaryIdsBuffer * Data = (lprofBinaryIdsBuffer * )This -> WriterCtx ;
988
+ for (uint64_t I = 0 ; I < BinaryIdLen ; I ++ ) {
989
+ Data -> Length +=
990
+ snprintf (Data -> String + Data -> Length , BINARY_ID_LEN + 1 - Data -> Length ,
991
+ "%02hhx" , BinaryIdData [I ]);
992
+ }
993
+ return 0 ;
994
+ }
995
+
955
996
/* Return the pointer to the current profile file name (after substituting
956
997
* PIDs and Hostnames in filename pattern. \p FilenameBuf is the buffer
957
998
* to store the resulting filename. If no substitution is needed, the
@@ -965,7 +1006,8 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
965
1006
return 0 ;
966
1007
967
1008
if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
968
- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ||
1009
+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
1010
+ lprofCurFilename .MergePoolSize ||
969
1011
__llvm_profile_is_continuous_mode_enabled ())) {
970
1012
if (!ForceUseBuf )
971
1013
return lprofCurFilename .FilenamePat ;
@@ -992,6 +1034,12 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
992
1034
memcpy (FilenameBuf + J , lprofCurFilename .TmpDir , TmpDirLength );
993
1035
FilenameBuf [J + TmpDirLength ] = DIR_SEPARATOR ;
994
1036
J += TmpDirLength + 1 ;
1037
+ } else if (FilenamePat [I ] == 'b' ) {
1038
+ lprofBinaryIdsBuffer Data = {{0 }, 0 };
1039
+ ProfDataWriter Writer = {binaryIdsStringWriter , & Data };
1040
+ __llvm_write_binary_ids (& Writer );
1041
+ memcpy (FilenameBuf + J , Data .String , Data .Length );
1042
+ J += Data .Length ;
995
1043
} else {
996
1044
if (!getMergePoolSize (FilenamePat , & I ))
997
1045
continue ;
0 commit comments