diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -122,11 +122,23 @@ uint32_t NumIOVecs) { uint32_t I; FILE *File = (FILE *)This->WriterCtx; + char Zeroes[sizeof(uint64_t)] = {0}; for (I = 0; I < NumIOVecs; I++) { if (IOVecs[I].Data) { if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) != IOVecs[I].NumElm) return 1; + } else if (IOVecs[I].UseZeroPadding) { + size_t BytesToWrite = IOVecs[I].ElmSize * IOVecs[I].NumElm; + while (BytesToWrite > 0) { + size_t PartialWriteLen = + (sizeof(uint64_t) > BytesToWrite) ? BytesToWrite : sizeof(uint64_t); + if (fwrite(Zeroes, sizeof(uint8_t), PartialWriteLen, File) != + PartialWriteLen) { + return 1; + } + BytesToWrite -= PartialWriteLen; + } } else { if (fseek(File, IOVecs[I].ElmSize * IOVecs[I].NumElm, SEEK_CUR) == -1) return 1; diff --git a/compiler-rt/lib/profile/InstrProfilingInternal.h b/compiler-rt/lib/profile/InstrProfilingInternal.h --- a/compiler-rt/lib/profile/InstrProfilingInternal.h +++ b/compiler-rt/lib/profile/InstrProfilingInternal.h @@ -41,11 +41,18 @@ /*! * The data structure describing the data to be written by the * low level writer callback function. + * + * If \ref ProfDataIOVec.Data is null, and \ref ProfDataIOVec.UseZeroPadding is + * 0, the write is skipped (the writer simply advances ElmSize*NumElm bytes). + * + * If \ref ProfDataIOVec.Data is null, and \ref ProfDataIOVec.UseZeroPadding is + * nonzero, ElmSize*NumElm zero bytes are written. */ typedef struct ProfDataIOVec { const void *Data; size_t ElmSize; size_t NumElm; + int UseZeroPadding; } ProfDataIOVec; struct ProfDataWriter; diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c b/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c --- a/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c @@ -128,6 +128,8 @@ __llvm_profile_offset, Length); if (Status != ZX_OK) return -1; + } else if (IOVecs[I].UseZeroPadding) { + /* Resizing the VMO should zero fill. */ } __llvm_profile_offset += Length; } diff --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c --- a/compiler-rt/lib/profile/InstrProfilingWriter.c +++ b/compiler-rt/lib/profile/InstrProfilingWriter.c @@ -41,6 +41,9 @@ size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm; if (IOVecs[I].Data) memcpy(*Buffer, IOVecs[I].Data, Length); + else if (IOVecs[I].UseZeroPadding) { + /* Allocating the buffer should zero fill. */ + } *Buffer += Length; } return 0; @@ -85,7 +88,7 @@ return -1; } /* Special case, bypass the buffer completely. */ - ProfDataIOVec IO[] = {{Data, sizeof(uint8_t), Size}}; + ProfDataIOVec IO[] = {{Data, sizeof(uint8_t), Size, 0}}; if (Size > BufferIO->BufferSz) { if (BufferIO->FileWriter->Write(BufferIO->FileWriter, IO, 1)) return -1; @@ -104,7 +107,7 @@ COMPILER_RT_VISIBILITY int lprofBufferIOFlush(ProfBufferIO *BufferIO) { if (BufferIO->CurOffset) { ProfDataIOVec IO[] = { - {BufferIO->BufferStart, sizeof(uint8_t), BufferIO->CurOffset}}; + {BufferIO->BufferStart, sizeof(uint8_t), BufferIO->CurOffset, 0}}; if (BufferIO->FileWriter->Write(BufferIO->FileWriter, IO, 1)) return -1; BufferIO->CurOffset = 0; @@ -259,11 +262,6 @@ const uint64_t CountersSize = CountersEnd - CountersBegin; const uint64_t NamesSize = NamesEnd - NamesBegin; - /* Enough zeroes for padding. */ - unsigned PageSize = getpagesize(); - char *Zeroes = (char *)COMPILER_RT_ALLOCA(PageSize); - memset(Zeroes, 0, PageSize); - /* Create the header. */ __llvm_profile_header Header; @@ -284,13 +282,13 @@ /* Write the data. */ ProfDataIOVec IOVec[] = { - {&Header, sizeof(__llvm_profile_header), 1}, - {DataBegin, sizeof(__llvm_profile_data), DataSize}, - {Zeroes, sizeof(uint8_t), PaddingBytesBeforeCounters}, - {CountersBegin, sizeof(uint64_t), CountersSize}, - {Zeroes, sizeof(uint8_t), PaddingBytesAfterCounters}, - {SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize}, - {Zeroes, sizeof(uint8_t), PaddingBytesAfterNames}}; + {&Header, sizeof(__llvm_profile_header), 1, 0}, + {DataBegin, sizeof(__llvm_profile_data), DataSize, 0}, + {NULL, sizeof(uint8_t), PaddingBytesBeforeCounters, 1}, + {CountersBegin, sizeof(uint64_t), CountersSize, 0}, + {NULL, sizeof(uint8_t), PaddingBytesAfterCounters, 1}, + {SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize, 0}, + {NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1}}; if (Writer->Write(Writer, IOVec, sizeof(IOVec) / sizeof(*IOVec))) return -1;