COMPILER_RT_VISIBILITY
int __llvm_profile_write_file(void) {
  int rc;

  GetEnvHook = &getenv;
  /* Check the filename. */
  if (!__llvm_profile_CurrentFilename) {
    PROF_ERR("LLVM Profile: Failed to write file : %s\n", "Filename not set");
    return -1;
  }

  /* Check if there is llvm/runtime version mismatch.  */
  if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) {
    PROF_ERR("LLVM Profile: runtime and instrumentation version mismatch : "
             "expected %d, but get %d\n",
             INSTR_PROF_RAW_VERSION,
             (int)GET_VERSION(__llvm_profile_get_version()));
    return -1;
  }

  /* Write the file. */
  rc = writeFileWithName(__llvm_profile_CurrentFilename);
  if (rc)
    PROF_ERR("LLVM Profile: Failed to write file \"%s\": %s\n",
            __llvm_profile_CurrentFilename, strerror(errno));
  return rc;
}
/* The public API for writing profile data into the file with name
 * set by previous calls to __llvm_profile_set_filename or
 * __llvm_profile_override_default_filename or
 * __llvm_profile_initialize_file. */
COMPILER_RT_VISIBILITY
int __llvm_profile_write_file(void) {
    int rc, Length;
    const char *Filename;
    char *FilenameBuf;

    Length = getCurFilenameLength();
    FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
    Filename = getCurFilename(FilenameBuf);

    /* Check the filename. */
    if (!Filename) {
        PROF_ERR("Failed to write file : %s\n", "Filename not set");
        return -1;
    }

    /* Check if there is llvm/runtime version mismatch.  */
    if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) {
        PROF_ERR("Runtime and instrumentation version mismatch : "
                 "expected %d, but get %d\n",
                 INSTR_PROF_RAW_VERSION,
                 (int)GET_VERSION(__llvm_profile_get_version()));
        return -1;
    }

    /* Write profile data to the file. */
    rc = writeFile(Filename);
    if (rc)
        PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));
    return rc;
}
static int dump(void) {
  if (lprofProfileDumped()) {
    lprofWrite("Profile data not published: already written.\n");
    return 0;
  }

  /* Check if there is llvm/runtime version mismatch. */
  if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) {
    lprofWrite("Runtime and instrumentation version mismatch : "
               "expected %d, but got %d\n",
               INSTR_PROF_RAW_VERSION,
               (int)GET_VERSION(__llvm_profile_get_version()));
    return -1;
  }

  /* Write the profile data into the mapped region. */
  ProfDataWriter VMOWriter;
  initVMOWriter(&VMOWriter);
  if (lprofWriteData(&VMOWriter, lprofGetVPDataReader(), 0) != 0)
    return -1;

  return 0;
}
int __llvm_profile_write_buffer(char *Buffer) {
  /* Match logic in __llvm_profile_get_size_for_buffer().
   * Match logic in __llvm_profile_write_file().
   */
  const __llvm_profile_data *DataBegin = __llvm_profile_data_begin();
  const __llvm_profile_data *DataEnd = __llvm_profile_data_end();
  const uint64_t *CountersBegin = __llvm_profile_counters_begin();
  const uint64_t *CountersEnd   = __llvm_profile_counters_end();
  const char *NamesBegin = __llvm_profile_names_begin();
  const char *NamesEnd   = __llvm_profile_names_end();

  /* Calculate size of sections. */
  const uint64_t DataSize = DataEnd - DataBegin;
  const uint64_t CountersSize = CountersEnd - CountersBegin;
  const uint64_t NamesSize = NamesEnd - NamesBegin;
  const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);

  /* Enough zeroes for padding. */
  const char Zeroes[sizeof(uint64_t)] = {0};

  /* Create the header. */
  uint64_t Header[PROFILE_HEADER_SIZE];
  Header[0] = __llvm_profile_get_magic();
  Header[1] = __llvm_profile_get_version();
  Header[2] = DataSize;
  Header[3] = CountersSize;
  Header[4] = NamesSize;
  Header[5] = (uintptr_t)CountersBegin;
  Header[6] = (uintptr_t)NamesBegin;

  /* Write the data. */
#define UPDATE_memcpy(Data, Size) \
  do {                            \
    memcpy(Buffer, Data, Size);   \
    Buffer += Size;               \
  } while (0)
  UPDATE_memcpy(Header,  PROFILE_HEADER_SIZE * sizeof(uint64_t));
  UPDATE_memcpy(DataBegin,     DataSize      * sizeof(__llvm_profile_data));
  UPDATE_memcpy(CountersBegin, CountersSize  * sizeof(uint64_t));
  UPDATE_memcpy(NamesBegin,    NamesSize     * sizeof(char));
  UPDATE_memcpy(Zeroes,        Padding       * sizeof(char));
#undef UPDATE_memcpy

  return 0;
}
Exemple #5
0
/* Returns 1 if profile is not structurally compatible.  */
COMPILER_RT_VISIBILITY
int __llvm_profile_check_compatibility(const char *ProfileData,
                                       uint64_t ProfileSize) {
  /* Check profile header only for now  */
  __llvm_profile_header *Header = (__llvm_profile_header *)ProfileData;
  __llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData;
  SrcDataStart =
      (__llvm_profile_data *)(ProfileData + sizeof(__llvm_profile_header));
  SrcDataEnd = SrcDataStart + Header->DataSize;

  if (ProfileSize < sizeof(__llvm_profile_header))
    return 1;

  /* Check the header first.  */
  if (Header->Magic != __llvm_profile_get_magic() ||
      Header->Version != __llvm_profile_get_version() ||
      Header->DataSize !=
          __llvm_profile_get_data_size(__llvm_profile_begin_data(),
                                       __llvm_profile_end_data()) ||
      Header->CountersSize != (uint64_t)(__llvm_profile_end_counters() -
                                         __llvm_profile_begin_counters()) ||
      Header->NamesSize != (uint64_t)(__llvm_profile_end_names() -
                                      __llvm_profile_begin_names()) ||
      Header->ValueKindLast != IPVK_Last)
    return 1;

  if (ProfileSize < sizeof(__llvm_profile_header) +
                        Header->DataSize * sizeof(__llvm_profile_data) +
                        Header->NamesSize + Header->CountersSize)
    return 1;

  for (SrcData = SrcDataStart,
       DstData = (__llvm_profile_data *)__llvm_profile_begin_data();
       SrcData < SrcDataEnd; ++SrcData, ++DstData) {
    if (SrcData->NameRef != DstData->NameRef ||
        SrcData->FuncHash != DstData->FuncHash ||
        SrcData->NumCounters != DstData->NumCounters)
      return 1;
  }

  /* Matched! */
  return 0;
}
int __llvm_profile_write_buffer_internal(
    char *Buffer, const __llvm_profile_data *DataBegin,
    const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,
    const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) {
  /* Match logic in __llvm_profile_get_size_for_buffer().
   * Match logic in __llvm_profile_write_file().
   */

  /* Calculate size of sections. */
  const uint64_t DataSize = DataEnd - DataBegin;
  const uint64_t CountersSize = CountersEnd - CountersBegin;
  const uint64_t NamesSize = NamesEnd - NamesBegin;
  const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);

  /* Enough zeroes for padding. */
  const char Zeroes[sizeof(uint64_t)] = {0};

  /* Create the header. */
  __llvm_profile_header Header;
  Header.Magic = __llvm_profile_get_magic();
  Header.Version = __llvm_profile_get_version();
  Header.DataSize = DataSize;
  Header.CountersSize = CountersSize;
  Header.NamesSize = NamesSize;
  Header.CountersDelta = (uintptr_t)CountersBegin;
  Header.NamesDelta = (uintptr_t)NamesBegin;

  /* Write the data. */
#define UPDATE_memcpy(Data, Size) \
  do {                            \
    memcpy(Buffer, Data, Size);   \
    Buffer += Size;               \
  } while (0)
  UPDATE_memcpy(&Header,  sizeof(__llvm_profile_header));
  UPDATE_memcpy(DataBegin,     DataSize      * sizeof(__llvm_profile_data));
  UPDATE_memcpy(CountersBegin, CountersSize  * sizeof(uint64_t));
  UPDATE_memcpy(NamesBegin,    NamesSize     * sizeof(char));
  UPDATE_memcpy(Zeroes,        Padding       * sizeof(char));
#undef UPDATE_memcpy

  return 0;
}
int __llvm_profile_write_buffer(char *Buffer) {
  /* Match logic in __llvm_profile_get_size_for_buffer().
   * Match logic in __llvm_profile_write_file().
   */
  const __llvm_profile_data *DataBegin = __llvm_profile_data_begin();
  const __llvm_profile_data *DataEnd = __llvm_profile_data_end();
  const uint64_t *CountersBegin = __llvm_profile_counters_begin();
  const uint64_t *CountersEnd   = __llvm_profile_counters_end();
  const char *NamesBegin = __llvm_profile_names_begin();
  const char *NamesEnd   = __llvm_profile_names_end();

  /* Calculate size of sections. */
  const uint64_t DataSize = DataEnd - DataBegin;
  const uint64_t CountersSize = CountersEnd - CountersBegin;
  const uint64_t NamesSize = NamesEnd - NamesBegin;

  /* Create the header. */
  uint64_t Header[PROFILE_HEADER_SIZE] = {
    __llvm_profile_get_magic(),
    __llvm_profile_get_version(),
    DataSize,
    CountersSize,
    NamesSize,
    (uintptr_t)CountersBegin,
    (uintptr_t)NamesBegin
  };

  /* Write the data. */
#define UPDATE_memcpy(Data, Size) \
  do {                            \
    memcpy(Buffer, Data, Size);   \
    Buffer += Size;               \
  } while (0)
  UPDATE_memcpy(Header,  PROFILE_HEADER_SIZE * sizeof(uint64_t));
  UPDATE_memcpy(DataBegin,     DataSize      * sizeof(__llvm_profile_data));
  UPDATE_memcpy(CountersBegin, CountersSize  * sizeof(uint64_t));
  UPDATE_memcpy(NamesBegin,    NamesSize     * sizeof(char));
#undef UPDATE_memcpy

  return 0;
}
Exemple #8
0
static int writeFile(FILE *File) {
  /* Match logic in __llvm_profile_write_buffer(). */
  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
  const uint64_t *CountersBegin = __llvm_profile_begin_counters();
  const uint64_t *CountersEnd   = __llvm_profile_end_counters();
  const char *NamesBegin = __llvm_profile_begin_names();
  const char *NamesEnd   = __llvm_profile_end_names();

  /* Calculate size of sections. */
  const uint64_t DataSize = DataEnd - DataBegin;
  const uint64_t CountersSize = CountersEnd - CountersBegin;
  const uint64_t NamesSize = NamesEnd - NamesBegin;
  const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);

  /* Enough zeroes for padding. */
  const char Zeroes[sizeof(uint64_t)] = {0};

  /* Create the header. */
  uint64_t Header[PROFILE_HEADER_SIZE];
  Header[0] = __llvm_profile_get_magic();
  Header[1] = __llvm_profile_get_version();
  Header[2] = DataSize;
  Header[3] = CountersSize;
  Header[4] = NamesSize;
  Header[5] = (uintptr_t)CountersBegin;
  Header[6] = (uintptr_t)NamesBegin;

  /* Write the data. */
#define CHECK_fwrite(Data, Size, Length, File) \
  do { if (fwrite(Data, Size, Length, File) != Length) return -1; } while (0)
  CHECK_fwrite(Header,        sizeof(uint64_t), PROFILE_HEADER_SIZE, File);
  CHECK_fwrite(DataBegin,     sizeof(__llvm_profile_data), DataSize, File);
  CHECK_fwrite(CountersBegin, sizeof(uint64_t), CountersSize, File);
  CHECK_fwrite(NamesBegin,    sizeof(char), NamesSize, File);
  CHECK_fwrite(Zeroes,        sizeof(char), Padding, File);
#undef CHECK_fwrite

  return 0;
}