/* 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_MODULE_H #define _COLLECTOR_MODULE_H #include #include #include #include #include #include #include "gp-defs.h" struct stat; struct tm; #define COLLECTOR_MODULE_ERR ((CollectorModule)-1) /* ------- libc interface ----------------- */ /* the fields in this structure are in alphabetical order. * If you add any, please put it in the right place */ typedef struct CollectorUtilFuncs { int (*access)(); int (*atoi)(const char *nptr); void *(*calloc)(size_t nelem, size_t elsize); int (*clearenv)(void); int (*close)(int); int (*closedir)(); int (*execv)(const char *path, char *const argv[]); void (*exit)(int status); int (*fclose)(FILE *stream); int (*fcntl)(int fd, int cmd, ...); char *(*fgets)(char *s, int n, FILE *stream); FILE *(*fopen)(const char *filename, const char *mode); pid_t (*vfork)(); int (*fprintf)(FILE *stream, const char *format, ...); void (*free)(void *ptr); int (*fstat)(int fd, struct stat *buf); int (*getcontext)(ucontext_t *ucp); int (*getcpuid)(); char *(*getcwd)(char *buf, size_t size); char *(*getenv)(const char *name); struct tm *(*gmtime_r)(const time_t *clock, struct tm *res); int (*ioctl)(int d, int request, ...); off_t (*lseek)(int fd, off_t offset, int whence); void *(*malloc)(size_t size); void *(*memset)(void *s1, int c, size_t n); int (*mkdir)(); time_t (*mktime)(struct tm *timeptr); void *(*mmap)(void *, size_t, int, int, int, off_t); void *(*mmap64_)(); int (*munmap)(); int (*open)(const char *, int, ...); int (*open_bare)(const char *, int, ...); DIR *(*opendir)(); int (*pclose)(FILE *stream); FILE *(*popen)(const char *command, const char *mode); int (*putenv)(char *string); ssize_t (*pwrite)(); ssize_t (*pwrite64_)(); ssize_t (*read)(); int (*setenv)(const char *name, const char *value, int overwrite); int (*sigfillset)(sigset_t *set); int (*sigprocmask)(int how, const sigset_t *set, sigset_t *oldset); int (*snprintf)(char *str, size_t size, const char *format, ...); int (*stack_getbounds)(); char *(*strchr)(const char *name, int c); int (*strcmp)(const char *s1, const char *s2); int (*strcpy)(const char *s1, const char *s2); char *(*libc_strdup)(const char *s1); // Don't use "strdup" because it is a macro in gcc char *(*strerror)(int errnum); int (*strerror_r)(int errnum, char *strerrbuf, size_t buflen); size_t (*strlcat)(char *dest, const char *src, size_t dstsize); size_t (*strlcpy)(char *dest, const char *src, size_t dstsize); size_t (*strlen)(const char *string); int (*strncmp)(const char *s1, const char *s2, size_t n); size_t (*strncpy)(char *dst, const char *src, size_t dstsize); size_t (*strspn)(const char *s1, const char *s2); char *(*strrchr)(const char *name, int c); char *(*strstr)(const char *s1, const char *s2); long int (*strtol)(const char *nptr, char **endptr, int base); long long int (*strtoll)(const char *nptr, char **endptr, int base); unsigned long int (*strtoul)(const char *nptr, char **endptr, int base); unsigned long long int (*strtoull)(const char *nptr, char **endptr, int base); int (*symlink)(const char *s1, const char *s2); int (*syscall)(int number, ...); long (*sysconf)(int name); long (*sysinfo)(int command, char *buf, long count); time_t (*time)(time_t *tloc); int (*unsetenv)(const char *name); int (*vsnprintf)(char *str, size_t size, const char *format, va_list ap); pid_t (*waitpid)(pid_t pid, int *stat_loc, int options); ssize_t (*write)(); double (*atof)(); void *n_a; } CollectorUtilFuncs; extern CollectorUtilFuncs __collector_util_funcs; extern int __collector_dlsym_guard; #define CALL_UTIL(x) __collector_util_funcs.x /* The following constants define the meaning of the "void *arg" * argument of getFrameInfo(). */ /* arg is a pointer to ucontext_t, walk the stack described by it */ #define FRINFO_FROM_UC 1 /* walk the current stack starting from the frame containing arg */ #define FRINFO_FROM_STACK 2 /* walk the current stack starting from the caller of the frame containing arg */ #define FRINFO_FROM_STACK_ARG 3 /* arg is a pc, process a stack containing just that pc */ #define FRINFO_FROM_PC 4 /* arg is of type CM_Array describing a stack image */ #define FRINFO_FROM_ARRAY 5 #define FRINFO_NO_OMP_INFO 0x80000000 #define FRINFO_NO_WALK 0x40000000 typedef struct CM_Array { unsigned int length; /* in bytes, not including length */ void *bytes; } CM_Array; // Interface with libcollector.so: typedef enum { SP_ORIGIN_FORK = -1, SP_ORIGIN_LIBCOL_INIT = 0, SP_ORIGIN_DBX_ATTACH = 1, SP_ORIGIN_GENEXP = 2, SP_ORIGIN_KERNEL = 3, SP_ORIGIN_DTRACE = 4, SP_ORIGIN_COLLECT = 5 } sp_origin_t; struct Heap; struct Common_packet; struct CM_Packet; struct ModuleInterface; typedef long long HiResTime; typedef int CollectorModule; typedef unsigned long long FrameInfo; typedef struct CollectorInterface { /* General services */ CollectorModule (*registerModule)(struct ModuleInterface*); const char *(*getParams)(); const char *(*getExpDir)(); int (*writeLog)(char *format, ...); FrameInfo (*getFrameInfo)(CollectorModule modl, HiResTime ts, int mode, void *arg); FrameInfo (*getUID)(CM_Array *arg); FrameInfo (*getUID2)(CM_Array *arg, FrameInfo uid); int (*getStackTrace)(void *buf, int size, void *bptr, void *eptr, void *arg); int (*writeMetaData)(CollectorModule modl, char *format, ...); /* writeDataRecord ensures that the header is filled in, and then calls writeDataPacket */ int (*writeDataRecord)(CollectorModule modl, struct Common_packet *pckt); int (*writeDataPacket)(CollectorModule modl, struct CM_Packet *pckt); void (*write_sample)(char *name); void (*get_progspec)(char *retstr, int tmp_sz, char *namestr, int name_sz); int (*open_experiment)(const char *exp, const char *params, sp_origin_t origin); HiResTime (*getHiResTime)(); /* Dynamic memory allocation service */ struct Heap *(*newHeap)(); void (*deleteHeap)(struct Heap *heap); void *(*allocCSize)(struct Heap *heap, unsigned sz, int log); void (*freeCSize)(struct Heap *heap, void *ptr, unsigned sz); void *(*allocVSize)(struct Heap *heap, unsigned sz); void *(*reallocVSize)(struct Heap *heap, void *ptr, unsigned newsz); /* Thread specific data service */ unsigned (*createKey)(size_t sz, void (*init)(void*), void (*fini)(void*)); void *(*getKey)(unsigned key); /* Debugging services */ void (*writeDebugInfo)(int, int, char *, ...) __attribute__ ((format (printf, 3, 4))); } CollectorInterface; typedef struct ModuleInterface { char *description; int (*initInterface)(CollectorInterface*); int (*openExperiment)(const char *); int (*startDataCollection)(); int (*stopDataCollection)(); int (*closeExperiment)(); int (*detachExperiment)(); /* called from fork-child before openExperiment() */ } ModuleInterface; typedef CollectorModule (*RegModuleFunc)(ModuleInterface*); typedef void (*ModuleInitFunc)(CollectorInterface*); #ifdef __cplusplus extern "C" { #endif CollectorModule __collector_register_module (ModuleInterface *modint); #ifdef __cplusplus } #endif #ifdef __has_attribute # if __has_attribute (__symver__) # define SYMVER_ATTRIBUTE(sym, symver) \ __attribute__ ((__symver__ (#symver))) # endif #endif #ifndef SYMVER_ATTRIBUTE # define SYMVER_ATTRIBUTE(sym, symver) \ __asm__(".symver " #sym "," #symver); #endif #endif /* _COLLECTOR_MODULE_H */