xref: /minix3/sys/external/bsd/compiler_rt/dist/lib/profile/InstrProfilingBuffer.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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 Sambuc uint64_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 Sambuc int __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