12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/*===- InstrProfilingBuffer.c - Write instrumentation to a memory buffer --===*\
22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines|*
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines|*                     The LLVM Compiler Infrastructure
42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines|*
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines|* This file is distributed under the University of Illinois Open Source
62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines|* License. See LICENSE.TXT for details.
72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines|*
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines\*===----------------------------------------------------------------------===*/
92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "InstrProfiling.h"
112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <string.h>
122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__attribute__((visibility("hidden")))
142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesuint64_t __llvm_profile_get_size_for_buffer(void) {
152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  /* Match logic in __llvm_profile_write_buffer(). */
162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t NamesSize = PROFILE_RANGE_SIZE(names) * sizeof(char);
172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return sizeof(uint64_t) * PROFILE_HEADER_SIZE +
192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     PROFILE_RANGE_SIZE(data) * sizeof(__llvm_profile_data) +
202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     PROFILE_RANGE_SIZE(counters) * sizeof(uint64_t) +
212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines     NamesSize + Padding;
222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__attribute__((visibility("hidden")))
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint __llvm_profile_write_buffer(char *Buffer) {
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  /* Match logic in __llvm_profile_get_size_for_buffer().
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   * Match logic in __llvm_profile_write_file().
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines   */
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const __llvm_profile_data *DataBegin = __llvm_profile_data_begin();
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const __llvm_profile_data *DataEnd = __llvm_profile_data_end();
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t *CountersBegin = __llvm_profile_counters_begin();
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t *CountersEnd   = __llvm_profile_counters_end();
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const char *NamesBegin = __llvm_profile_names_begin();
342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const char *NamesEnd   = __llvm_profile_names_end();
352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  /* Calculate size of sections. */
372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t DataSize = DataEnd - DataBegin;
382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t CountersSize = CountersEnd - CountersBegin;
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t NamesSize = NamesEnd - NamesBegin;
402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  /* Enough zeroes for padding. */
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  const char Zeroes[sizeof(uint64_t)] = {0};
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  /* Create the header. */
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uint64_t Header[PROFILE_HEADER_SIZE];
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[0] = __llvm_profile_get_magic();
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[1] = __llvm_profile_get_version();
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[2] = DataSize;
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[3] = CountersSize;
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[4] = NamesSize;
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[5] = (uintptr_t)CountersBegin;
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  Header[6] = (uintptr_t)NamesBegin;
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  /* Write the data. */
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define UPDATE_memcpy(Data, Size) \
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  do {                            \
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    memcpy(Buffer, Data, Size);   \
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    Buffer += Size;               \
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } while (0)
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  UPDATE_memcpy(Header,  PROFILE_HEADER_SIZE * sizeof(uint64_t));
622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  UPDATE_memcpy(DataBegin,     DataSize      * sizeof(__llvm_profile_data));
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  UPDATE_memcpy(CountersBegin, CountersSize  * sizeof(uint64_t));
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  UPDATE_memcpy(NamesBegin,    NamesSize     * sizeof(char));
652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  UPDATE_memcpy(Zeroes,        Padding       * sizeof(char));
662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#undef UPDATE_memcpy
672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return 0;
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
70