]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/libcollector/libcol_util.h
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gprofng / libcollector / libcol_util.h
CommitLineData
fd67aa11 1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
bb368aad
VM
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 _LIBCOL_UTIL_H
22#define _LIBCOL_UTIL_H
23
24#include <stdarg.h>
25#include <pthread.h>
26#include <signal.h>
27
28// LIBCOLLECTOR NOT I18N
29#define NTXT(x) x
30#define STXT(x) x
31
32extern int __collector_tracelevel;
33
34/* Initialization function */
35extern int __collector_util_init();
36extern void __collector_libkstat_funcs_init();
37extern void __collector_libscf_funcs_init();
38
39/* ------- functions from libcol_util.c ----------------- */
40extern void * __collector_memcpy (void *s1, const void *s2, size_t n);
53beac2e
VM
41extern int (*__collector_sscanfp)(const char *restrict s, const char *restrict fmt, ...)
42 __attribute__ ((format (scanf, 2, 3)));
bb368aad
VM
43extern char * __collector_strcat (char *s1, const char *s2);
44extern char * __collector_strchr (const char *s1, int chr);
45extern size_t __collector_strlcpy (char *dst, const char *src, size_t dstsize);
46extern char* __collector_strrchr (const char *str, int chr);
47extern size_t __collector_strlen (const char *s);
48extern size_t __collector_strlcat (char *dst, const char *src, size_t dstsize);
49extern char* __collector_strchr (const char *str, int chr);
50extern int __collector_strcmp (const char *s1, const char *s2);
51extern int __collector_strncmp (const char *s1, const char *s2, size_t n);
52extern char * __collector_strstr (const char *s1, const char *s2);
53extern size_t __collector_strncpy (char *dst, const char *src, size_t dstsize);
54extern size_t __collector_strncat (char *dst, const char *src, size_t dstsize);
55extern void * __collector_malloc (size_t size);
56extern void * __collector_calloc (size_t nelem, size_t elsize);
57extern char * __collector_strdup (const char * str);
58extern int __collector_strStartWith (const char *s1, const char *s2);
59extern int __collector_xml_snprintf (char *s, size_t n, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
60extern int __collector_xml_vsnprintf (char *s, size_t n, const char *format, va_list args);
61
62/* ------- collector_thread ----------------- */
fe39ffdc 63extern pid_t __collector_gettid ();
bb368aad 64extern void __collector_ext_gettid_tsd_create_key ();
fe39ffdc
VM
65typedef pthread_t collector_thread_t;
66#define __collector_lwp_self() ((collector_thread_t) ((unsigned long) __collector_gettid()))
67#define __collector_thr_self() ((collector_thread_t) ((unsigned long) __collector_gettid()))
bb368aad
VM
68
69/* ------- collector_mutex ----------------- */
70/*
71 * mutex_init is defined in libthread. If we don't want to interact
72 * with libthread we should use memset to initialize mutexes
73 */
74
75typedef volatile int collector_mutex_t;
76#define COLLECTOR_MUTEX_INITIALIZER 0
77extern int __collector_mutex_lock (collector_mutex_t *mp);
78extern int __collector_mutex_unlock (collector_mutex_t *mp);
79extern int __collector_mutex_trylock (collector_mutex_t *mp);
80
81#define __collector_mutex_init(xx) \
82 do { collector_mutex_t tmp=COLLECTOR_MUTEX_INITIALIZER; *(xx)=tmp; } while(0)
83
84void __collector_sample (char *name);
85void __collector_terminate_expt ();
86void __collector_pause ();
87void __collector_pause_m ();
88void __collector_resume ();
89
90struct DT_lineno;
91
92typedef enum
93{
94 DFUNC_API = 1, /* dynamic function declared with API */
95 DFUNC_JAVA, /* dynamically compiled java method */
96 DFUNC_KERNEL /* dynamic code mapped by the kernel (Linux) */
97} dfunc_mode_t;
98
99extern void __collector_int_func_load (dfunc_mode_t mode, char *name,
100 char *sourcename, void *vaddr,
101 int size, int lntsize,
102 struct DT_lineno *lntable);
103extern void __collector_int_func_unload (dfunc_mode_t mode, void *vaddr);
104
105extern int __collector_sigaction (int sig, const struct sigaction *nact,
106 struct sigaction *oact);
107extern void __collector_SIGDFL_handler (int sig);
108extern int __collector_ext_itimer_set (int period);
109
110#if ARCH(Intel)
111/* Atomic functions on x86/x64 */
112
113/**
114 * This function enables the inrementing (by one) of the value stored in target
115 * to occur in an atomic manner.
116 */
117static __attribute__ ((always_inline)) inline void
118__collector_inc_32 (uint32_t *ptr)
119{
120 __asm__ __volatile__("lock; incl %0"
121 : // "=m" (*ptr) // output
122 : "m" (*ptr)); // input
123}
124
125/**
126 * This function enables the decrementing (by one) of the value stored in target
127 * to occur in an atomic manner.
128 */
129static __attribute__ ((always_inline)) inline void
130__collector_dec_32 (volatile uint32_t *ptr)
131{
132 __asm__ __volatile__("lock; decl %0"
133 : // "=m" (*ptr) // output
134 : "m" (*ptr)); // input
135}
2a2cb7cf 136
bb368aad
VM
137/**
138 * This function subtrackts the value "off" of the value stored in target
139 * to occur in an atomic manner, and returns new value stored in target.
140 */
141static __attribute__ ((always_inline)) inline uint32_t
142__collector_subget_32 (uint32_t *ptr, uint32_t off)
143{
144 uint32_t r;
145 uint32_t offset = off;
146 __asm__ __volatile__("movl %2, %0; negl %0; lock; xaddl %0, %1"
147 : "=r" (r), "=m" (*ptr) /* output */
148 : "a" (off), "r" (*ptr) /* input */
149 );
150 return (r - offset);
151}
2a2cb7cf 152
bb368aad
VM
153/**
154 * This function returns the value of the stack pointer register
155 */
156static __attribute__ ((always_inline)) inline void *
157__collector_getsp ()
158{
159 void *r;
2a2cb7cf 160#if WSIZE(32) || defined(__ILP32__)
bb368aad 161 __asm__ __volatile__("movl %%esp, %0"
2a2cb7cf
VM
162#else
163 __asm__ __volatile__("movq %%rsp, %0"
164#endif
bb368aad
VM
165 : "=r" (r)); // output
166 return r;
167}
2a2cb7cf 168
bb368aad
VM
169/**
170 * This function returns the value of the frame pointer register
171 */
172static __attribute__ ((always_inline)) inline void *
173__collector_getfp ()
174{
175 void *r;
2a2cb7cf 176#if WSIZE(32) || defined(__ILP32__)
bb368aad 177 __asm__ __volatile__("movl %%ebp, %0"
2a2cb7cf
VM
178#else
179 __asm__ __volatile__("movq %%rbp, %0"
bb368aad
VM
180#endif
181 : "=r" (r)); // output
182 return r;
183}
2a2cb7cf 184
bb368aad
VM
185/**
186 * This function returns the value of the processor counter register
187 */
188static __attribute__ ((always_inline)) inline void *
189__collector_getpc ()
190{
191 void *r;
2a2cb7cf
VM
192#if defined(__x86_64)
193 __asm__ __volatile__("lea (%%rip), %0" : "=r" (r));
bb368aad 194#else
2a2cb7cf
VM
195 __asm__ __volatile__("call 1f \n"
196 "1: popl %0" : "=r" (r));
bb368aad 197#endif
bb368aad
VM
198 return r;
199}
200
201/**
202 * This function enables a compare and swap operation to occur atomically.
203 * The 32-bit value stored in target is compared with "old". If these values
204 * are equal, the value stored in target is replaced with "new". The old
205 * 32-bit value stored in target is returned by the function whether or not
206 * the replacement occurred.
207 */
208static __attribute__ ((always_inline)) inline uint32_t
209__collector_cas_32 (volatile uint32_t *pdata, uint32_t old, uint32_t new)
210{
211 uint32_t r;
212 __asm__ __volatile__("lock; cmpxchgl %2, %1"
213 : "=a" (r), "=m" (*pdata) : "r" (new),
214 "a" (old), "m" (*pdata));
215 return r;
216}
217/**
218 * This function enables a compare and swap operation to occur atomically.
219 * The 64-bit value stored in target is compared with "old". If these values
220 * are equal, the value stored in target is replaced with "new". The old
221 * 64-bit value stored in target is returned by the function whether or not
222 * the replacement occurred.
223 */
224static __attribute__ ((always_inline)) inline uint64_t
225__collector_cas_64p (volatile uint64_t *mem, uint64_t *old, uint64_t * new)
226{
227 uint64_t r;
228#if WSIZE(32)
229 uint32_t old1 = (uint32_t) (*old & 0xFFFFFFFFL);
230 uint32_t old2 = (uint32_t) ((*old >> 32) & 0xFFFFFFFFL);
231 uint32_t new1 = (uint32_t) (*new & 0xFFFFFFFFL);
232 uint32_t new2 = (uint32_t) ((*new >> 32) & 0xFFFFFFFFL);
233 uint32_t res1 = 0;
234 uint32_t res2 = 0;
235 __asm__ __volatile__(
236 "movl %3, %%esi; lock; cmpxchg8b (%%esi); movl %%edx, %2; movl %%eax, %1"
237 : "=m" (r), "=m" (res1), "=m" (res2) /* output */
238 : "m" (mem), "a" (old1), "d" (old2), "b" (new1), "c" (new2) /* input */
239 : "memory", "cc", "esi" //, "edx", "ecx", "ebx", "eax" /* clobbered register */
240 );
241 r = (((uint64_t) res2) << 32) | ((uint64_t) res1);
242#else
243 __asm__ __volatile__( "lock; cmpxchgq %2, %1"
244 : "=a" (r), "=m" (*mem) /* output */
245 : "r" (*new), "a" (*old), "m" (*mem) /* input */
246 : "%rcx", "rdx" /* clobbered register */
247 );
248#endif
249 return r;
250}
251/**
252 * This function enables a compare and swap operation to occur atomically.
253 * The 32-/64-bit value stored in target is compared with "cmp". If these values
254 * are equal, the value stored in target is replaced with "new".
255 * The old value stored in target is returned by the function whether or not
256 * the replacement occurred.
257 */
258static __attribute__ ((always_inline)) inline void *
259__collector_cas_ptr (void *mem, void *cmp, void *new)
260{
261 void *r;
2a2cb7cf 262#if WSIZE(32) || defined(__ILP32__)
bb368aad
VM
263 r = (void *) __collector_cas_32 ((volatile uint32_t *)mem, (uint32_t) cmp, (uint32_t)new);
264#else
265 __asm__ __volatile__("lock; cmpxchgq %2, (%1)"
266 : "=a" (r), "=b" (mem) /* output */
267 : "r" (new), "a" (cmp), "b" (mem) /* input */
268 );
269#endif
270 return r;
271}
272
273#elif ARCH(Aarch64)
274static __attribute__ ((always_inline)) inline uint32_t
275__collector_inc_32 (volatile uint32_t *ptr)
276{
277 return __sync_add_and_fetch (ptr, 1);
278}
279
280static __attribute__ ((always_inline)) inline uint32_t
281__collector_dec_32 (volatile uint32_t *ptr)
282{
283 return __sync_sub_and_fetch (ptr, 1);
284}
285
286static __attribute__ ((always_inline)) inline uint32_t
287__collector_subget_32 (volatile uint32_t *ptr, uint32_t off)
288{
289 return __sync_sub_and_fetch (ptr, off);
290}
291
292static __attribute__ ((always_inline)) inline uint32_t
293__collector_cas_32 (volatile uint32_t *ptr, uint32_t old, uint32_t new)
294{
295 return __sync_val_compare_and_swap (ptr, old, new);
296}
297
298static __attribute__ ((always_inline)) inline uint64_t
299__collector_cas_64p (volatile uint64_t *ptr, uint64_t *old, uint64_t * new)
300{
301 return __sync_val_compare_and_swap (ptr, *old, *new);
302}
303
304static __attribute__ ((always_inline)) inline void *
305__collector_cas_ptr (void *ptr, void *old, void *new)
306{
307 return (void *) __sync_val_compare_and_swap ((unsigned long *) ptr, (unsigned long) old, (unsigned long) new);
308}
309
310#else
311extern void __collector_flushw (); /* defined for SPARC only */
312extern void* __collector_getpc ();
313extern void* __collector_getsp ();
314extern void* __collector_getfp ();
315extern void __collector_inc_32 (volatile uint32_t *);
316extern void __collector_dec_32 (volatile uint32_t *);
317extern void* __collector_cas_ptr (volatile void *, void *, void *);
318extern uint32_t __collector_cas_32 (volatile uint32_t *, uint32_t, uint32_t);
319extern uint32_t __collector_subget_32 (volatile uint32_t *, uint32_t);
320extern uint64_t __collector_cas_64p (volatile uint64_t *, uint64_t *, uint64_t *);
321#endif /* ARCH() */
322#endif /* _LIBCOL_UTIL_H */