1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#ifndef _COLLECTOR_H
22#define _COLLECTOR_H
23
24#include <signal.h>
25
26#include "gp-defs.h"
27#include "data_pckts.h"
28#include "libcol_util.h"
29#include "collector_module.h"
30
31#define GETRELTIME()    (__collector_gethrtime() - __collector_start_time)
32#define CALL_REAL(x)	(__real_##x)
33#define NULL_PTR(x)	(__real_##x == NULL)
34
35#define SYS_LIBC_NAME   "libc.so.6"
36
37#ifdef __has_attribute
38#if __has_attribute (__symver__)
39#define SYMVER_ATTRIBUTE(sym, symver)  __attribute__ ((__symver__ (#symver)))
40#endif
41#endif
42#ifndef SYMVER_ATTRIBUTE
43# define SYMVER_ATTRIBUTE(sym, symver)  __asm__(".symver " #sym "," #symver);
44#endif
45
46#if defined(__MUSL_LIBC)
47#define dlvsym(f, nm, v)  dlsym (f, nm)
48#define SIGEV_THREAD_ID   4
49#define DCL_FUNC_VER(REAL_DCL, sym, ver)
50#else
51#define DCL_FUNC_VER(REAL_DCL, sym, ver) \
52  SYMVER_ATTRIBUTE (__collector_ ## sym, ver) \
53  REAL_DCL (__collector_ ## sym)
54#endif
55
56extern hrtime_t __collector_start_time;
57
58/* ========================================================== */
59/* -------  internal function prototypes ----------------- */
60/* These will not be exported from libcollector.so */
61struct DataHandle;
62struct Heap;
63extern struct DataHandle *__collector_create_handle (char*);
64extern void __collector_delete_handle (struct DataHandle*);
65extern int __collector_write_record (struct DataHandle*, Common_packet*);
66extern int __collector_write_packet (struct DataHandle*, CM_Packet*);
67extern int __collector_write_string (struct DataHandle*, char*, int);
68extern FrameInfo __collector_get_frame_info (hrtime_t, int, void *);
69extern FrameInfo __collector_getUID (CM_Array *arg, FrameInfo uid);
70extern int __collector_getStackTrace (void *buf, int size, void *bptr,
71				      void *eptr, void *arg);
72extern void *__collector_ext_return_address (unsigned level);
73extern void __collector_mmap_fork_child_cleanup ();
74
75extern int __collector_ext_mmap_install (int);
76extern int __collector_ext_mmap_deinstall (int);
77extern int __collector_ext_update_map_segments (void);
78extern int __collector_check_segment (unsigned long addr,
79				      unsigned long *base,
80				      unsigned long *end, int maxnretries);
81extern int __collector_check_readable_segment (unsigned long addr,
82					       unsigned long *base,
83					       unsigned long *end, int maxnretries);
84extern int __collector_ext_line_init (int * pfollow_this_experiment,
85				      const char * progspec,
86				      const char *progname);
87extern int __collector_ext_line_install (char *, const char *);
88extern void __collector_ext_line_close ();
89extern void __collector_ext_unwind_init (int);
90extern void __collector_ext_unwind_close ();
91extern int __collector_ext_jstack_unwind (char*, int, ucontext_t *);
92extern void __collector_ext_dispatcher_fork_child_cleanup ();
93extern void __collector_ext_unwind_key_init (int isPthread, void * stack);
94extern void __collector_ext_dispatcher_tsd_create_key ();
95extern void __collector_ext_dispatcher_thread_timer_suspend ();
96extern int __collector_ext_dispatcher_thread_timer_resume ();
97extern int __collector_ext_dispatcher_install ();
98extern void __collector_ext_dispatcher_suspend ();
99extern void __collector_ext_dispatcher_restart ();
100extern void __collector_ext_dispatcher_deinstall ();
101extern void __collector_ext_usage_sample (Smpl_type type, char *name);
102extern void __collector_ext_profile_handler (siginfo_t *, ucontext_t *);
103extern int __collector_ext_clone_pthread (int (*fn)(void *), void *child_stack,
104					  int flags, void *arg, va_list va);
105extern int __collector_sigprof_install ();
106extern int __collector_ext_hwc_active ();
107extern void __collector_ext_hwc_check (siginfo_t *, ucontext_t *);
108extern int __collector_ext_hwc_lwp_init ();
109extern void __collector_ext_hwc_lwp_fini ();
110extern int __collector_ext_hwc_lwp_suspend ();
111extern int __collector_ext_hwc_lwp_resume ();
112extern int (*__collector_VM_ReadByteInstruction)(unsigned char *);
113extern int (*__collector_omp_stack_trace)(char*, int, hrtime_t, void*);
114extern hrtime_t (*__collector_gethrtime)();
115extern int (*__collector_mpi_stack_trace)(char*, int, hrtime_t);
116extern int __collector_open_experiment (const char *exp, const char *par,
117					sp_origin_t origin);
118extern void __collector_suspend_experiment (char *why);
119extern void __collector_resume_experiment ();
120extern void __collector_clean_state ();
121extern void __collector_close_experiment ();
122extern void __collector_terminate_expt ();
123extern void __collector_terminate_hook ();
124extern void __collector_sample (char *name);
125extern void __collector_pause ();
126extern void __collector_pause_m ();
127extern void __collector_resume ();
128extern int collector_sigemt_sigaction (const struct sigaction*,
129				       struct sigaction*);
130extern int collector_sigchld_sigaction (const struct sigaction*,
131					struct sigaction*);
132
133extern int
134__collector_log_write (char *format, ...) __attribute__ ((format (printf, 1, 2)));
135
136/* -------  internal global data ----------------- */
137/* These will not be exported from libcollector.so */
138extern struct Heap *__collector_heap;
139
140/* experiment state flag  */
141typedef enum
142{
143  EXP_INIT, EXP_OPEN, EXP_PAUSED, EXP_CLOSED
144} sp_state_t;
145extern volatile sp_state_t __collector_expstate;
146
147/* global flag, defines whether target is threaded or not
148 *   if set, put _lwp_self() for thread id instead of thr_self()
149 *	in output packets; should be set before any data packets
150 *	are written, i.e., before signal handlers are installed.
151 */
152extern int __collector_no_threads;
153extern int __collector_libthread_T1; /* T1 or not T1 */
154extern int __collector_sample_sig; /* set to signal used to trigger a sample */
155extern int __collector_sample_sig_warn; /* if 1, warning given on target use */
156extern int __collector_pause_sig; /* set to signal used to toggle pause-resume */
157extern int __collector_pause_sig_warn; /* if 1, warning given on target use */
158extern hrtime_t __collector_delay_start;
159extern int __collector_exp_active;
160
161/* global hrtime_t for next periodic sample */
162extern hrtime_t __collector_next_sample;
163extern int __collector_sample_period;
164
165/* global hrtime_t for experiment termination (-t) */
166extern hrtime_t __collector_terminate_time;
167extern int __collector_terminate_duration;
168extern char __collector_exp_dir_name[];
169extern int __collector_java_mode;
170extern int __collector_java_asyncgetcalltrace_loaded;
171extern int __collector_jprofile_start_attach ();
172
173/* --------- information controlling debug tracing ------------- */
174
175/* global flag, defines level of trace information */
176extern void __collector_dlog (int, int, char *, ...) __attribute__ ((format (printf, 3, 4)));
177
178#define STR(x)  ((x) ? (x) : "NULL")
179
180// To set collector_debug_opt use:
181//   SP_COLLECTOR_DEBUG=4 ; export SP_COLLECTOR_DEBUG ; collect ...
182enum
183{
184  SP_DUMP_TIME      = 1,
185  SP_DUMP_FLAG      = 2,
186  SP_DUMP_JAVA      = 4,
187  SP_DUMP_NOHEADER  = 8,
188  SP_DUMP_UNWIND    = 16,
189  SP_DUMP_STACK     = 32,
190};
191
192/* TprintfT(<level>,...) definitions.  Adjust per module as needed */
193enum
194{
195  DBG_LT0 = 0, // for high-level configuration, unexpected errors/warnings
196  DBG_LTT = 0, // for interposition on GLIBC functions
197  DBG_LT1 = 1, // for configuration details, warnings
198  DBG_LT2 = 2,
199  DBG_LT3 = 3,
200  DBG_LT4 = 4
201};
202
203#ifndef DEBUG
204#define DprintfT(flag, ...)
205#define tprintf(...)
206#define Tprintf(...)
207#define TprintfT(...)
208
209#else
210#define DprintfT(flag, ...)  __collector_dlog(SP_DUMP_FLAG | (flag), 0, __VA_ARGS__ )
211#define tprintf(...)  __collector_dlog( SP_DUMP_NOHEADER, __VA_ARGS__ )
212#define Tprintf(...)  __collector_dlog( 0, __VA_ARGS__ )
213#define TprintfT(...) __collector_dlog( SP_DUMP_TIME, __VA_ARGS__ )
214
215#endif /* DEBUG */
216
217#endif
218