blob: 8519891f2a974163081be6f0b745e4315603658b [file] [log] [blame]
Xinliang David Li1d8d46a2015-11-18 21:08:03 +00001/*===- InstrProfilingWriter.c - Write instrumentation to a file or buffer -===*\
2|*
3|* The LLVM Compiler Infrastructure
4|*
5|* This file is distributed under the University of Illinois Open Source
6|* License. See LICENSE.TXT for details.
7|*
8\*===----------------------------------------------------------------------===*/
9
10#include "InstrProfiling.h"
11#include "InstrProfilingInternal.h"
Xinliang David Libaf55d82015-12-22 18:57:15 +000012#include <string.h>
13
14/* The buffer writer is reponsponsible in keeping writer state
15 * across the call.
16 */
17COMPILER_RT_VISIBILITY uint32_t llvmBufferWriter(ProfDataIOVec *IOVecs,
18 uint32_t NumIOVecs,
19 void **WriterCtx) {
20 uint32_t I;
21 char **Buffer = (char **)WriterCtx;
22 for (I = 0; I < NumIOVecs; I++) {
23 size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm;
24 memcpy(*Buffer, IOVecs[I].Data, Length);
25 *Buffer += Length;
26 }
27 return 0;
28}
Xinliang David Li1d8d46a2015-11-18 21:08:03 +000029
Xinliang David Liabfd5532015-12-16 03:29:15 +000030COMPILER_RT_VISIBILITY int llvmWriteProfData(WriterCallback Writer,
31 void *WriterCtx,
32 const uint8_t *ValueDataBegin,
33 const uint64_t ValueDataSize) {
Xinliang David Li1d8d46a2015-11-18 21:08:03 +000034 /* Match logic in __llvm_profile_write_buffer(). */
35 const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
36 const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
37 const uint64_t *CountersBegin = __llvm_profile_begin_counters();
38 const uint64_t *CountersEnd = __llvm_profile_end_counters();
39 const char *NamesBegin = __llvm_profile_begin_names();
40 const char *NamesEnd = __llvm_profile_end_names();
Xinliang David Li2d5bf072015-11-21 04:16:42 +000041 return llvmWriteProfDataImpl(Writer, WriterCtx, DataBegin, DataEnd,
Xinliang David Li6e557162015-11-18 21:11:46 +000042 CountersBegin, CountersEnd, ValueDataBegin,
43 ValueDataSize, NamesBegin, NamesEnd);
Xinliang David Li1d8d46a2015-11-18 21:08:03 +000044}
45
Xinliang David Liabfd5532015-12-16 03:29:15 +000046COMPILER_RT_VISIBILITY int llvmWriteProfDataImpl(
Xinliang David Li2d5bf072015-11-21 04:16:42 +000047 WriterCallback Writer, void *WriterCtx,
Xinliang David Li1d8d46a2015-11-18 21:08:03 +000048 const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,
49 const uint64_t *CountersBegin, const uint64_t *CountersEnd,
50 const uint8_t *ValueDataBegin, const uint64_t ValueDataSize,
51 const char *NamesBegin, const char *NamesEnd) {
52
53 /* Calculate size of sections. */
54 const uint64_t DataSize = DataEnd - DataBegin;
55 const uint64_t CountersSize = CountersEnd - CountersBegin;
56 const uint64_t NamesSize = NamesEnd - NamesBegin;
57 const uint64_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);
58
59 /* Enough zeroes for padding. */
60 const char Zeroes[sizeof(uint64_t)] = {0};
61
62 /* Create the header. */
63 __llvm_profile_header Header;
64
65 if (!DataSize)
66 return 0;
67
Xinliang David Li6376db52015-11-23 18:36:40 +000068 /* Initialize header struture. */
69#define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init;
70#include "InstrProfData.inc"
Xinliang David Li1d8d46a2015-11-18 21:08:03 +000071
Xinliang David Li2d5bf072015-11-21 04:16:42 +000072 /* Write the data. */
73 ProfDataIOVec IOVec[] = {
Xinliang David Lif7185dc2015-11-21 07:26:46 +000074 {&Header, sizeof(__llvm_profile_header), 1},
75 {DataBegin, sizeof(__llvm_profile_data), DataSize},
76 {CountersBegin, sizeof(uint64_t), CountersSize},
77 {NamesBegin, sizeof(char), NamesSize},
78 {Zeroes, sizeof(char), Padding}};
Joerg Sonnenbergerd6487b22015-12-04 00:40:07 +000079 if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx))
Xinliang David Li2d5bf072015-11-21 04:16:42 +000080 return -1;
81 if (ValueDataBegin) {
Joerg Sonnenbergerd6487b22015-12-04 00:40:07 +000082 ProfDataIOVec IOVec2[] = {{ValueDataBegin, sizeof(char), ValueDataSize}};
83 if (Writer(IOVec2, sizeof(IOVec2) / sizeof(*IOVec2), &WriterCtx))
Xinliang David Li2d5bf072015-11-21 04:16:42 +000084 return -1;
85 }
Xinliang David Li1d8d46a2015-11-18 21:08:03 +000086 return 0;
87}