1/*===- InstrProfilingPlatformOther.c - Profile data default platform ------===*\
2|*
3|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4|* See https://llvm.org/LICENSE.txt for license information.
5|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6|*
7\*===----------------------------------------------------------------------===*/
8
9// This file defines a fallback implementation to compute the locations of
10// profile data sections, for targets that don't have linker support. No
11// commonly used targets use this codepath.
12//
13// This implementation expects the compiler instrumentation pass to define a
14// constructor in each file which calls into this file.
15
16#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \
17 !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \
18 !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && \
19 !defined(__wasm__) && !defined(__HAIKU__) && \
20 !defined(COMPILER_RT_PROFILE_BAREMETAL)
21
22#include <stdlib.h>
23#include <stdio.h>
24
25#include "InstrProfiling.h"
26#include "InstrProfilingInternal.h"
27
28static const __llvm_profile_data *DataFirst = NULL;
29static const __llvm_profile_data *DataLast = NULL;
30static const VTableProfData *VTableProfDataFirst = NULL;
31static const VTableProfData *VTableProfDataLast = NULL;
32static const char *NamesFirst = NULL;
33static const char *NamesLast = NULL;
34static const char *VNamesFirst = NULL;
35static const char *VNamesLast = NULL;
36static char *CountersFirst = NULL;
37static char *CountersLast = NULL;
38
39static const void *getMinAddr(const void *A1, const void *A2) {
40 return A1 < A2 ? A1 : A2;
41}
42
43static const void *getMaxAddr(const void *A1, const void *A2) {
44 return A1 > A2 ? A1 : A2;
45}
46
47/*!
48 * \brief Register an instrumented function.
49 *
50 * Calls to this are emitted by clang with -fprofile-instr-generate. Such
51 * calls are only required (and only emitted) on targets where we haven't
52 * implemented linker magic to find the bounds of the sections.
53 */
54COMPILER_RT_VISIBILITY
55void __llvm_profile_register_function(void *Data_) {
56 /* TODO: Only emit this function if we can't use linker magic. */
57 const __llvm_profile_data *Data = (__llvm_profile_data *)Data_;
58 if (!DataFirst) {
59 DataFirst = Data;
60 DataLast = Data + 1;
61 CountersFirst = (char *)((uintptr_t)Data_ + Data->CounterPtr);
62 CountersLast =
63 CountersFirst + Data->NumCounters * __llvm_profile_counter_entry_size();
64 return;
65 }
66
67 DataFirst = (const __llvm_profile_data *)getMinAddr(DataFirst, Data);
68 CountersFirst = (char *)getMinAddr(
69 CountersFirst, (char *)((uintptr_t)Data_ + Data->CounterPtr));
70
71 DataLast = (const __llvm_profile_data *)getMaxAddr(DataLast, Data + 1);
72 CountersLast = (char *)getMaxAddr(
73 CountersLast,
74 (char *)((uintptr_t)Data_ + Data->CounterPtr) +
75 Data->NumCounters * __llvm_profile_counter_entry_size());
76}
77
78COMPILER_RT_VISIBILITY
79void __llvm_profile_register_names_function(void *NamesStart,
80 uint64_t NamesSize) {
81 if (!NamesFirst) {
82 NamesFirst = (const char *)NamesStart;
83 NamesLast = (const char *)NamesStart + NamesSize;
84 return;
85 }
86 NamesFirst = (const char *)getMinAddr(NamesFirst, NamesStart);
87 NamesLast =
88 (const char *)getMaxAddr(NamesLast, (const char *)NamesStart + NamesSize);
89}
90
91COMPILER_RT_VISIBILITY
92const __llvm_profile_data *__llvm_profile_begin_data(void) { return DataFirst; }
93COMPILER_RT_VISIBILITY
94const __llvm_profile_data *__llvm_profile_end_data(void) { return DataLast; }
95COMPILER_RT_VISIBILITY const VTableProfData *
96__llvm_profile_begin_vtables(void) {
97 return VTableProfDataFirst;
98}
99COMPILER_RT_VISIBILITY const VTableProfData *__llvm_profile_end_vtables(void) {
100 return VTableProfDataLast;
101}
102COMPILER_RT_VISIBILITY
103const char *__llvm_profile_begin_names(void) { return NamesFirst; }
104COMPILER_RT_VISIBILITY
105const char *__llvm_profile_end_names(void) { return NamesLast; }
106COMPILER_RT_VISIBILITY
107const char *__llvm_profile_begin_vtabnames(void) { return VNamesFirst; }
108COMPILER_RT_VISIBILITY
109const char *__llvm_profile_end_vtabnames(void) { return VNamesLast; }
110COMPILER_RT_VISIBILITY
111char *__llvm_profile_begin_counters(void) { return CountersFirst; }
112COMPILER_RT_VISIBILITY
113char *__llvm_profile_end_counters(void) { return CountersLast; }
114COMPILER_RT_VISIBILITY
115char *__llvm_profile_begin_bitmap(void) { return BitmapFirst; }
116COMPILER_RT_VISIBILITY
117char *__llvm_profile_end_bitmap(void) { return BitmapLast; }
118
119COMPILER_RT_VISIBILITY
120ValueProfNode *__llvm_profile_begin_vnodes(void) {
121 return 0;
122}
123COMPILER_RT_VISIBILITY
124ValueProfNode *__llvm_profile_end_vnodes(void) { return 0; }
125
126COMPILER_RT_VISIBILITY ValueProfNode *CurrentVNode = 0;
127COMPILER_RT_VISIBILITY ValueProfNode *EndVNode = 0;
128
129COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) {
130 return 0;
131}
132
133#endif
134