/* Copyright (C) 2021-2023 Free Software Foundation, Inc. Contributed by Oracle. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _COLLECTOR_H #define _COLLECTOR_H #include #include "gp-defs.h" #include "data_pckts.h" #include "libcol_util.h" #include "collector_module.h" #define GETRELTIME() (__collector_gethrtime() - __collector_start_time) #if defined(__MUSL_LIBC) #define dlvsym(f, nm, v) dlsym (f, nm) #define SIGEV_THREAD_ID 4 #endif extern hrtime_t __collector_start_time; /* ========================================================== */ /* ------- internal function prototypes ----------------- */ /* These will not be exported from libcollector.so */ struct DataHandle; struct Heap; extern struct DataHandle *__collector_create_handle (char*); extern void __collector_delete_handle (struct DataHandle*); extern int __collector_write_record (struct DataHandle*, Common_packet*); extern int __collector_write_packet (struct DataHandle*, CM_Packet*); extern int __collector_write_string (struct DataHandle*, char*, int); extern FrameInfo __collector_get_frame_info (hrtime_t, int, void *); extern FrameInfo __collector_getUID (CM_Array *arg, FrameInfo uid); extern int __collector_getStackTrace (void *buf, int size, void *bptr, void *eptr, void *arg); extern void *__collector_ext_return_address (unsigned level); extern void __collector_mmap_fork_child_cleanup (); extern int __collector_ext_mmap_install (int); extern int __collector_ext_mmap_deinstall (int); extern int __collector_ext_update_map_segments (void); extern int __collector_check_segment (unsigned long addr, unsigned long *base, unsigned long *end, int maxnretries); extern int __collector_check_readable_segment (unsigned long addr, unsigned long *base, unsigned long *end, int maxnretries); extern int __collector_ext_line_init (int * pfollow_this_experiment, const char * progspec, const char *progname); extern int __collector_ext_line_install (char *, const char *); extern void __collector_ext_line_close (); extern void __collector_ext_unwind_init (int); extern void __collector_ext_unwind_close (); extern int __collector_ext_jstack_unwind (char*, int, ucontext_t *); extern void __collector_ext_dispatcher_fork_child_cleanup (); extern void __collector_ext_unwind_key_init (int isPthread, void * stack); extern void __collector_ext_dispatcher_tsd_create_key (); extern void __collector_ext_dispatcher_thread_timer_suspend (); extern int __collector_ext_dispatcher_thread_timer_resume (); extern int __collector_ext_dispatcher_install (); extern void __collector_ext_dispatcher_suspend (); extern void __collector_ext_dispatcher_restart (); extern void __collector_ext_dispatcher_deinstall (); extern void __collector_ext_usage_sample (Smpl_type type, char *name); extern void __collector_ext_profile_handler (siginfo_t *, ucontext_t *); extern int __collector_ext_clone_pthread (int (*fn)(void *), void *child_stack, int flags, void *arg, va_list va /* pid_t *ptid, struct user_desc *tlspid_t *" ctid" */); /* D-light related functions */ extern int __collector_sigprof_install (); extern int __collector_ext_hwc_active (); extern void __collector_ext_hwc_check (siginfo_t *, ucontext_t *); extern int __collector_ext_hwc_lwp_init (); extern void __collector_ext_hwc_lwp_fini (); extern int __collector_ext_hwc_lwp_suspend (); extern int __collector_ext_hwc_lwp_resume (); extern int (*__collector_VM_ReadByteInstruction)(unsigned char *); extern int (*__collector_omp_stack_trace)(char*, int, hrtime_t, void*); extern hrtime_t (*__collector_gethrtime)(); extern int (*__collector_mpi_stack_trace)(char*, int, hrtime_t); extern int __collector_open_experiment (const char *exp, const char *par, sp_origin_t origin); extern void __collector_suspend_experiment (char *why); extern void __collector_resume_experiment (); extern void __collector_clean_state (); extern void __collector_close_experiment (); extern void __collector_terminate_expt (); extern void __collector_terminate_hook (); extern void __collector_sample (char *name); extern void __collector_pause (); extern void __collector_pause_m (); extern void __collector_resume (); extern int collector_sigemt_sigaction (const struct sigaction*, struct sigaction*); extern int collector_sigchld_sigaction (const struct sigaction*, struct sigaction*); extern int __collector_log_write (char *format, ...) __attribute__ ((format (printf, 1, 2))); /* ------- internal global data ----------------- */ /* These will not be exported from libcollector.so */ extern struct Heap *__collector_heap; /* experiment state flag */ typedef enum { EXP_INIT, EXP_OPEN, EXP_PAUSED, EXP_CLOSED } sp_state_t; extern volatile sp_state_t __collector_expstate; /* global flag, defines whether target is threaded or not * if set, put _lwp_self() for thread id instead of thr_self() * in output packets; should be set before any data packets * are written, i.e., before signal handlers are installed. */ extern int __collector_no_threads; extern int __collector_libthread_T1; /* T1 or not T1 */ extern int __collector_sample_sig; /* set to signal used to trigger a sample */ extern int __collector_sample_sig_warn; /* if 1, warning given on target use */ extern int __collector_pause_sig; /* set to signal used to toggle pause-resume */ extern int __collector_pause_sig_warn; /* if 1, warning given on target use */ extern hrtime_t __collector_delay_start; extern int __collector_exp_active; /* global hrtime_t for next periodic sample */ extern hrtime_t __collector_next_sample; extern int __collector_sample_period; /* global hrtime_t for experiment termination (-t) */ extern hrtime_t __collector_terminate_time; extern int __collector_terminate_duration; extern char __collector_exp_dir_name[]; extern int __collector_java_mode; extern int __collector_java_asyncgetcalltrace_loaded; extern int __collector_jprofile_start_attach (); /* --------- information controlling debug tracing ------------- */ /* global flag, defines level of trace information */ extern void __collector_dlog (int, int, char *, ...) __attribute__ ((format (printf, 3, 4))); #define STR(x) ((x) ? (x) : "NULL") // To set collector_debug_opt use: // SP_COLLECTOR_DEBUG=4 ; export SP_COLLECTOR_DEBUG ; collect ... enum { SP_DUMP_TIME = 1, SP_DUMP_FLAG = 2, SP_DUMP_JAVA = 4, SP_DUMP_NOHEADER = 8, SP_DUMP_UNWIND = 16, SP_DUMP_STACK = 32, }; #ifndef DEBUG #define DprintfT(flag, ...) #define tprintf(...) #define Tprintf(...) #define TprintfT(...) #else #define DprintfT(flag, ...) __collector_dlog(SP_DUMP_FLAG | (flag), 0, __VA_ARGS__ ) #define tprintf(...) __collector_dlog( SP_DUMP_NOHEADER, __VA_ARGS__ ) #define Tprintf(...) __collector_dlog( 0, __VA_ARGS__ ) #define TprintfT(...) __collector_dlog( SP_DUMP_TIME, __VA_ARGS__ ) #endif /* DEBUG */ // To find the glibc version: // objdump -T /lib*/*so /lib*/*/*.so | grep popen // IMPORTANT: The GLIBC_* versions below must match those in mapfile. #if ARCH(Aarch64) #define SYS_LIBC_NAME "libc.so.6" #define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.17" #define SYS_DLOPEN_VERSION "GLIBC_2.17" #define SYS_POPEN_VERSION "GLIBC_2.17" #define SYS_FOPEN_X_VERSION "GLIBC_2.17" #define SYS_FGETPOS_X_VERSION "GLIBC_2.17" #elif ARCH(Intel) #define SYS_LIBC_NAME "libc.so.6" #define SYS_POSIX_SPAWN_VERSION "GLIBC_2.15" #if WSIZE(32) #define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.1" #define SYS_DLOPEN_VERSION "GLIBC_2.1" #define SYS_POPEN_VERSION "GLIBC_2.1" #define SYS_TIMER_X_VERSION "GLIBC_2.2" #define SYS_FOPEN_X_VERSION "GLIBC_2.1" #define SYS_FGETPOS_X_VERSION "GLIBC_2.2" #define SYS_FGETPOS64_X_VERSION "GLIBC_2.2" #define SYS_OPEN64_X_VERSION "GLIBC_2.2" #define SYS_PREAD_X_VERSION "GLIBC_2.2" #define SYS_PWRITE_X_VERSION "GLIBC_2.2" #define SYS_PWRITE64_X_VERSION "GLIBC_2.2" #else /* WSIZE(64) */ #define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.2.5" #define SYS_DLOPEN_VERSION "GLIBC_2.2.5" #define SYS_POPEN_VERSION "GLIBC_2.2.5" #define SYS_TIMER_X_VERSION "GLIBC_2.3.3" #define SYS_FOPEN_X_VERSION "GLIBC_2.2.5" #define SYS_FGETPOS_X_VERSION "GLIBC_2.2.5" #endif #elif ARCH(SPARC) #define SYS_LIBC_NAME "libc.so.6" #define SYS_DLOPEN_VERSION "GLIBC_2.1" #if WSIZE(32) #define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.1" #define SYS_POPEN_VERSION "GLIBC_2.1" #define SYS_FOPEN_X_VERSION "GLIBC_2.1" #define SYS_FGETPOS_X_VERSION "GLIBC_2.2" #else /* WSIZE(64) */ #define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.2" #define SYS_POPEN_VERSION "GLIBC_2.2" #define SYS_TIMER_X_VERSION "GLIBC_2.3.3" #define SYS_FOPEN_X_VERSION "GLIBC_2.2" #define SYS_FGETPOS_X_VERSION "GLIBC_2.2" #endif #endif #endif