|  | /* Copyright (C) 2021 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 <signal.h> | 
|  |  | 
|  | #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.<variant> | 
|  | #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 |