1*0a6a1f1dSLionel Sambuc /*===- InstrProfilingBuffer.c - Write instrumentation to a memory buffer --===*\ 2*0a6a1f1dSLionel Sambuc |* 3*0a6a1f1dSLionel Sambuc |* The LLVM Compiler Infrastructure 4*0a6a1f1dSLionel Sambuc |* 5*0a6a1f1dSLionel Sambuc |* This file is distributed under the University of Illinois Open Source 6*0a6a1f1dSLionel Sambuc |* License. See LICENSE.TXT for details. 7*0a6a1f1dSLionel Sambuc |* 8*0a6a1f1dSLionel Sambuc \*===----------------------------------------------------------------------===*/ 9*0a6a1f1dSLionel Sambuc 10*0a6a1f1dSLionel Sambuc #include "InstrProfiling.h" 11*0a6a1f1dSLionel Sambuc #include <string.h> 12*0a6a1f1dSLionel Sambuc 13*0a6a1f1dSLionel Sambuc __attribute__((visibility("hidden"))) __llvm_profile_get_size_for_buffer(void)14*0a6a1f1dSLionel Sambucuint64_t __llvm_profile_get_size_for_buffer(void) { 15*0a6a1f1dSLionel Sambuc /* Match logic in __llvm_profile_write_buffer(). */ 16*0a6a1f1dSLionel Sambuc const uint64_t NamesSize = PROFILE_RANGE_SIZE(names) * sizeof(char); 17*0a6a1f1dSLionel Sambuc const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t); 18*0a6a1f1dSLionel Sambuc return sizeof(uint64_t) * PROFILE_HEADER_SIZE + 19*0a6a1f1dSLionel Sambuc PROFILE_RANGE_SIZE(data) * sizeof(__llvm_profile_data) + 20*0a6a1f1dSLionel Sambuc PROFILE_RANGE_SIZE(counters) * sizeof(uint64_t) + 21*0a6a1f1dSLionel Sambuc NamesSize + Padding; 22*0a6a1f1dSLionel Sambuc } 23*0a6a1f1dSLionel Sambuc 24*0a6a1f1dSLionel Sambuc __attribute__((visibility("hidden"))) __llvm_profile_write_buffer(char * Buffer)25*0a6a1f1dSLionel Sambucint __llvm_profile_write_buffer(char *Buffer) { 26*0a6a1f1dSLionel Sambuc /* Match logic in __llvm_profile_get_size_for_buffer(). 27*0a6a1f1dSLionel Sambuc * Match logic in __llvm_profile_write_file(). 28*0a6a1f1dSLionel Sambuc */ 29*0a6a1f1dSLionel Sambuc const __llvm_profile_data *DataBegin = __llvm_profile_data_begin(); 30*0a6a1f1dSLionel Sambuc const __llvm_profile_data *DataEnd = __llvm_profile_data_end(); 31*0a6a1f1dSLionel Sambuc const uint64_t *CountersBegin = __llvm_profile_counters_begin(); 32*0a6a1f1dSLionel Sambuc const uint64_t *CountersEnd = __llvm_profile_counters_end(); 33*0a6a1f1dSLionel Sambuc const char *NamesBegin = __llvm_profile_names_begin(); 34*0a6a1f1dSLionel Sambuc const char *NamesEnd = __llvm_profile_names_end(); 35*0a6a1f1dSLionel Sambuc 36*0a6a1f1dSLionel Sambuc /* Calculate size of sections. */ 37*0a6a1f1dSLionel Sambuc const uint64_t DataSize = DataEnd - DataBegin; 38*0a6a1f1dSLionel Sambuc const uint64_t CountersSize = CountersEnd - CountersBegin; 39*0a6a1f1dSLionel Sambuc const uint64_t NamesSize = NamesEnd - NamesBegin; 40*0a6a1f1dSLionel Sambuc const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t); 41*0a6a1f1dSLionel Sambuc 42*0a6a1f1dSLionel Sambuc /* Enough zeroes for padding. */ 43*0a6a1f1dSLionel Sambuc const char Zeroes[sizeof(uint64_t)] = {0}; 44*0a6a1f1dSLionel Sambuc 45*0a6a1f1dSLionel Sambuc /* Create the header. */ 46*0a6a1f1dSLionel Sambuc uint64_t Header[PROFILE_HEADER_SIZE]; 47*0a6a1f1dSLionel Sambuc Header[0] = __llvm_profile_get_magic(); 48*0a6a1f1dSLionel Sambuc Header[1] = __llvm_profile_get_version(); 49*0a6a1f1dSLionel Sambuc Header[2] = DataSize; 50*0a6a1f1dSLionel Sambuc Header[3] = CountersSize; 51*0a6a1f1dSLionel Sambuc Header[4] = NamesSize; 52*0a6a1f1dSLionel Sambuc Header[5] = (uintptr_t)CountersBegin; 53*0a6a1f1dSLionel Sambuc Header[6] = (uintptr_t)NamesBegin; 54*0a6a1f1dSLionel Sambuc 55*0a6a1f1dSLionel Sambuc /* Write the data. */ 56*0a6a1f1dSLionel Sambuc #define UPDATE_memcpy(Data, Size) \ 57*0a6a1f1dSLionel Sambuc do { \ 58*0a6a1f1dSLionel Sambuc memcpy(Buffer, Data, Size); \ 59*0a6a1f1dSLionel Sambuc Buffer += Size; \ 60*0a6a1f1dSLionel Sambuc } while (0) 61*0a6a1f1dSLionel Sambuc UPDATE_memcpy(Header, PROFILE_HEADER_SIZE * sizeof(uint64_t)); 62*0a6a1f1dSLionel Sambuc UPDATE_memcpy(DataBegin, DataSize * sizeof(__llvm_profile_data)); 63*0a6a1f1dSLionel Sambuc UPDATE_memcpy(CountersBegin, CountersSize * sizeof(uint64_t)); 64*0a6a1f1dSLionel Sambuc UPDATE_memcpy(NamesBegin, NamesSize * sizeof(char)); 65*0a6a1f1dSLionel Sambuc UPDATE_memcpy(Zeroes, Padding * sizeof(char)); 66*0a6a1f1dSLionel Sambuc #undef UPDATE_memcpy 67*0a6a1f1dSLionel Sambuc 68*0a6a1f1dSLionel Sambuc return 0; 69*0a6a1f1dSLionel Sambuc } 70