The !associated metadata may be attached to a global object declaration with a single argument that references another global object. This metadata prevents discarding of the global object in linker GC unless the referenced object is also discarded. Furthermore, when a function symbol is discarded by the linker, setting up !associated metadata allows linker to discard counters, data and values associated with that function symbol. This is not possible today because there's metadata to guide the linker. This approach is also used by other instrumentations like sanitizers. Note that !associated metadata is only supported by ELF, it does not have any effect on non-ELF targets. Differential Revision: https://reviews.llvm.org/D76802
78 lines
3.3 KiB
C
78 lines
3.3 KiB
C
/*===- InstrProfilingPlatformLinux.c - Profile data Linux platform ------===*\
|
|
|*
|
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|* See https://llvm.org/LICENSE.txt for license information.
|
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|*
|
|
\*===----------------------------------------------------------------------===*/
|
|
|
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
|
|
(defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__)
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "InstrProfiling.h"
|
|
|
|
#define PROF_DATA_START INSTR_PROF_SECT_START(INSTR_PROF_DATA_COMMON)
|
|
#define PROF_DATA_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_DATA_COMMON)
|
|
#define PROF_NAME_START INSTR_PROF_SECT_START(INSTR_PROF_NAME_COMMON)
|
|
#define PROF_NAME_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_NAME_COMMON)
|
|
#define PROF_CNTS_START INSTR_PROF_SECT_START(INSTR_PROF_CNTS_COMMON)
|
|
#define PROF_CNTS_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_CNTS_COMMON)
|
|
#define PROF_ORDERFILE_START INSTR_PROF_SECT_START(INSTR_PROF_ORDERFILE_COMMON)
|
|
#define PROF_VNODES_START INSTR_PROF_SECT_START(INSTR_PROF_VNODES_COMMON)
|
|
#define PROF_VNODES_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_VNODES_COMMON)
|
|
|
|
/* Declare section start and stop symbols for various sections
|
|
* generated by compiler instrumentation. These symbols are
|
|
* declared as weak, which means that they'll end up as NULL if
|
|
* those sections are empty, and any code that iterates over the
|
|
* content using __llvm_profile_begin_* and __llvm_profile_end_*
|
|
* functions defined below will be a no-op.
|
|
*/
|
|
extern __llvm_profile_data PROF_DATA_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern __llvm_profile_data PROF_DATA_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern uint64_t PROF_CNTS_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern uint32_t PROF_ORDERFILE_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern char PROF_NAME_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern ValueProfNode PROF_VNODES_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
extern ValueProfNode PROF_VNODES_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK;
|
|
|
|
COMPILER_RT_VISIBILITY const __llvm_profile_data *
|
|
__llvm_profile_begin_data(void) {
|
|
return &PROF_DATA_START;
|
|
}
|
|
COMPILER_RT_VISIBILITY const __llvm_profile_data *
|
|
__llvm_profile_end_data(void) {
|
|
return &PROF_DATA_STOP;
|
|
}
|
|
COMPILER_RT_VISIBILITY const char *__llvm_profile_begin_names(void) {
|
|
return &PROF_NAME_START;
|
|
}
|
|
COMPILER_RT_VISIBILITY const char *__llvm_profile_end_names(void) {
|
|
return &PROF_NAME_STOP;
|
|
}
|
|
COMPILER_RT_VISIBILITY uint64_t *__llvm_profile_begin_counters(void) {
|
|
return &PROF_CNTS_START;
|
|
}
|
|
COMPILER_RT_VISIBILITY uint64_t *__llvm_profile_end_counters(void) {
|
|
return &PROF_CNTS_STOP;
|
|
}
|
|
COMPILER_RT_VISIBILITY uint32_t *__llvm_profile_begin_orderfile(void) {
|
|
return &PROF_ORDERFILE_START;
|
|
}
|
|
|
|
COMPILER_RT_VISIBILITY ValueProfNode *
|
|
__llvm_profile_begin_vnodes(void) {
|
|
return &PROF_VNODES_START;
|
|
}
|
|
COMPILER_RT_VISIBILITY ValueProfNode *__llvm_profile_end_vnodes(void) {
|
|
return &PROF_VNODES_STOP;
|
|
}
|
|
COMPILER_RT_VISIBILITY ValueProfNode *CurrentVNode = &PROF_VNODES_START;
|
|
COMPILER_RT_VISIBILITY ValueProfNode *EndVNode = &PROF_VNODES_STOP;
|
|
|
|
#endif
|