1*0b57cec5SDimitry Andric /*===- InstrProfilingPlatformOther.c - Profile data default platform ------===*\ 2*0b57cec5SDimitry Andric |* 3*0b57cec5SDimitry Andric |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric |* See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric |* 7*0b57cec5SDimitry Andric \*===----------------------------------------------------------------------===*/ 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \ 10*0b57cec5SDimitry Andric !(defined(__sun__) && defined(__svr4__)) && !defined(__NetBSD__) && \ 11*0b57cec5SDimitry Andric !defined(_WIN32) 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include <stdlib.h> 14*0b57cec5SDimitry Andric #include <stdio.h> 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "InstrProfiling.h" 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric static const __llvm_profile_data *DataFirst = NULL; 19*0b57cec5SDimitry Andric static const __llvm_profile_data *DataLast = NULL; 20*0b57cec5SDimitry Andric static const char *NamesFirst = NULL; 21*0b57cec5SDimitry Andric static const char *NamesLast = NULL; 22*0b57cec5SDimitry Andric static uint64_t *CountersFirst = NULL; 23*0b57cec5SDimitry Andric static uint64_t *CountersLast = NULL; 24*0b57cec5SDimitry Andric static uint32_t *OrderFileFirst = NULL; 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric static const void *getMinAddr(const void *A1, const void *A2) { 27*0b57cec5SDimitry Andric return A1 < A2 ? A1 : A2; 28*0b57cec5SDimitry Andric } 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric static const void *getMaxAddr(const void *A1, const void *A2) { 31*0b57cec5SDimitry Andric return A1 > A2 ? A1 : A2; 32*0b57cec5SDimitry Andric } 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric /*! 35*0b57cec5SDimitry Andric * \brief Register an instrumented function. 36*0b57cec5SDimitry Andric * 37*0b57cec5SDimitry Andric * Calls to this are emitted by clang with -fprofile-instr-generate. Such 38*0b57cec5SDimitry Andric * calls are only required (and only emitted) on targets where we haven't 39*0b57cec5SDimitry Andric * implemented linker magic to find the bounds of the sections. 40*0b57cec5SDimitry Andric */ 41*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 42*0b57cec5SDimitry Andric void __llvm_profile_register_function(void *Data_) { 43*0b57cec5SDimitry Andric /* TODO: Only emit this function if we can't use linker magic. */ 44*0b57cec5SDimitry Andric const __llvm_profile_data *Data = (__llvm_profile_data *)Data_; 45*0b57cec5SDimitry Andric if (!DataFirst) { 46*0b57cec5SDimitry Andric DataFirst = Data; 47*0b57cec5SDimitry Andric DataLast = Data + 1; 48*0b57cec5SDimitry Andric CountersFirst = Data->CounterPtr; 49*0b57cec5SDimitry Andric CountersLast = (uint64_t *)Data->CounterPtr + Data->NumCounters; 50*0b57cec5SDimitry Andric return; 51*0b57cec5SDimitry Andric } 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric DataFirst = (const __llvm_profile_data *)getMinAddr(DataFirst, Data); 54*0b57cec5SDimitry Andric CountersFirst = (uint64_t *)getMinAddr(CountersFirst, Data->CounterPtr); 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric DataLast = (const __llvm_profile_data *)getMaxAddr(DataLast, Data + 1); 57*0b57cec5SDimitry Andric CountersLast = (uint64_t *)getMaxAddr( 58*0b57cec5SDimitry Andric CountersLast, (uint64_t *)Data->CounterPtr + Data->NumCounters); 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 62*0b57cec5SDimitry Andric void __llvm_profile_register_names_function(void *NamesStart, 63*0b57cec5SDimitry Andric uint64_t NamesSize) { 64*0b57cec5SDimitry Andric if (!NamesFirst) { 65*0b57cec5SDimitry Andric NamesFirst = (const char *)NamesStart; 66*0b57cec5SDimitry Andric NamesLast = (const char *)NamesStart + NamesSize; 67*0b57cec5SDimitry Andric return; 68*0b57cec5SDimitry Andric } 69*0b57cec5SDimitry Andric NamesFirst = (const char *)getMinAddr(NamesFirst, NamesStart); 70*0b57cec5SDimitry Andric NamesLast = 71*0b57cec5SDimitry Andric (const char *)getMaxAddr(NamesLast, (const char *)NamesStart + NamesSize); 72*0b57cec5SDimitry Andric } 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 75*0b57cec5SDimitry Andric const __llvm_profile_data *__llvm_profile_begin_data(void) { return DataFirst; } 76*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 77*0b57cec5SDimitry Andric const __llvm_profile_data *__llvm_profile_end_data(void) { return DataLast; } 78*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 79*0b57cec5SDimitry Andric const char *__llvm_profile_begin_names(void) { return NamesFirst; } 80*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 81*0b57cec5SDimitry Andric const char *__llvm_profile_end_names(void) { return NamesLast; } 82*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 83*0b57cec5SDimitry Andric uint64_t *__llvm_profile_begin_counters(void) { return CountersFirst; } 84*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 85*0b57cec5SDimitry Andric uint64_t *__llvm_profile_end_counters(void) { return CountersLast; } 86*0b57cec5SDimitry Andric /* TODO: correctly set up OrderFileFirst. */ 87*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 88*0b57cec5SDimitry Andric uint32_t *__llvm_profile_begin_orderfile(void) { return OrderFileFirst; } 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 91*0b57cec5SDimitry Andric ValueProfNode *__llvm_profile_begin_vnodes(void) { 92*0b57cec5SDimitry Andric return 0; 93*0b57cec5SDimitry Andric } 94*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY 95*0b57cec5SDimitry Andric ValueProfNode *__llvm_profile_end_vnodes(void) { return 0; } 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY ValueProfNode *CurrentVNode = 0; 98*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY ValueProfNode *EndVNode = 0; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric #endif 101