@@ -77,6 +77,7 @@ typedef struct lprofFilename {
7777 char Hostname [COMPILER_RT_MAX_HOSTLEN ];
7878 unsigned NumPids ;
7979 unsigned NumHosts ;
80+ unsigned NumBinaryIds ;
8081 /* When in-process merging is enabled, this parameter specifies
8182 * the total number of profile data files shared by all the processes
8283 * spawned from the same binary. By default the value is 1. If merging
@@ -88,8 +89,8 @@ typedef struct lprofFilename {
8889 ProfileNameSpecifier PNS ;
8990} lprofFilename ;
9091
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 };
9394
9495static int ProfileMergeRequested = 0 ;
9596static int getProfileFileSizeForMerging (FILE * ProfileFile ,
@@ -790,7 +791,7 @@ static int checkBounds(int Idx, int Strlen) {
790791 * lprofcurFilename structure. */
791792static int parseFilenamePattern (const char * FilenamePat ,
792793 unsigned CopyFilenamePat ) {
793- int NumPids = 0 , NumHosts = 0 , I ;
794+ int NumPids = 0 , NumHosts = 0 , NumBinaryIds = 0 , I ;
794795 char * PidChars = & lprofCurFilename .PidChars [0 ];
795796 char * Hostname = & lprofCurFilename .Hostname [0 ];
796797 int MergingEnabled = 0 ;
@@ -855,6 +856,16 @@ static int parseFilenamePattern(const char *FilenamePat,
855856 FilenamePat );
856857 return -1 ;
857858 }
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+ }
858869 } else if (FilenamePat [I ] == 'c' ) {
859870 if (__llvm_profile_is_continuous_mode_enabled ()) {
860871 PROF_WARN ("%%c specifier can only be specified once in %s.\n" ,
@@ -887,6 +898,7 @@ static int parseFilenamePattern(const char *FilenamePat,
887898
888899 lprofCurFilename .NumPids = NumPids ;
889900 lprofCurFilename .NumHosts = NumHosts ;
901+ lprofCurFilename .NumBinaryIds = NumBinaryIds ;
890902 return 0 ;
891903}
892904
@@ -934,24 +946,53 @@ static void parseAndSetFilename(const char *FilenamePat,
934946 * filename with PID and hostname substitutions. */
935947/* The length to hold uint64_t followed by 3 digits pool id including '_' */
936948#define SIGLEN 24
949+ /* The length to hold 160-bit hash in hexadecimal form */
950+ #define BINARY_ID_LEN 40
937951static int getCurFilenameLength (void ) {
938952 int Len ;
939953 if (!lprofCurFilename .FilenamePat || !lprofCurFilename .FilenamePat [0 ])
940954 return 0 ;
941955
942956 if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
943- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ))
957+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
958+ lprofCurFilename .MergePoolSize ))
944959 return strlen (lprofCurFilename .FilenamePat );
945960
946961 Len = strlen (lprofCurFilename .FilenamePat ) +
947962 lprofCurFilename .NumPids * (strlen (lprofCurFilename .PidChars ) - 2 ) +
948963 lprofCurFilename .NumHosts * (strlen (lprofCurFilename .Hostname ) - 2 ) +
964+ lprofCurFilename .NumBinaryIds * BINARY_ID_LEN +
949965 (lprofCurFilename .TmpDir ? (strlen (lprofCurFilename .TmpDir ) - 1 ) : 0 );
950966 if (lprofCurFilename .MergePoolSize )
951967 Len += SIGLEN ;
952968 return Len ;
953969}
954970
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+
955996/* Return the pointer to the current profile file name (after substituting
956997 * PIDs and Hostnames in filename pattern. \p FilenameBuf is the buffer
957998 * to store the resulting filename. If no substitution is needed, the
@@ -965,7 +1006,8 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
9651006 return 0 ;
9661007
9671008 if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
968- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ||
1009+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
1010+ lprofCurFilename .MergePoolSize ||
9691011 __llvm_profile_is_continuous_mode_enabled ())) {
9701012 if (!ForceUseBuf )
9711013 return lprofCurFilename .FilenamePat ;
@@ -992,6 +1034,12 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
9921034 memcpy (FilenameBuf + J , lprofCurFilename .TmpDir , TmpDirLength );
9931035 FilenameBuf [J + TmpDirLength ] = DIR_SEPARATOR ;
9941036 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 ;
9951043 } else {
9961044 if (!getMergePoolSize (FilenamePat , & I ))
9971045 continue ;
0 commit comments