GDB (xrefs)
Loading...
Searching...
No Matches
gmp-utils.h
Go to the documentation of this file.
1/* Miscellaneous routines making it easier to use GMP within GDB's framework.
2
3 Copyright (C) 2019-2023 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#ifndef GMP_UTILS_H
21#define GMP_UTILS_H
22
23/* Include <stdio.h> and <stdarg.h> ahead of <gmp.h>, so as to get
24 access to GMP's various formatting functions. */
25#include <stdio.h>
26#include <stdarg.h>
27#include <gmp.h>
28#include "gdbsupport/traits.h"
29
30/* Same as gmp_asprintf, but returning an std::string. */
31
32std::string gmp_string_printf (const char *fmt, ...);
33
34struct gdb_mpq;
35struct gdb_mpf;
36
37/* A class to make it easier to use GMP's mpz_t values within GDB. */
38
39struct gdb_mpz
40{
41 /* Constructors. */
42 gdb_mpz () { mpz_init (m_val); }
43
44 explicit gdb_mpz (const mpz_t &from_val)
45 {
46 mpz_init (m_val);
47 mpz_set (m_val, from_val);
48 }
49
50 gdb_mpz (const gdb_mpz &from)
51 {
52 mpz_init (m_val);
53 mpz_set (m_val, from.m_val);
54 }
55
56 /* Initialize using the given integral value.
57
58 The main advantage of this method is that it handles both signed
59 and unsigned types, with no size restriction. */
60 template<typename T, typename = gdb::Requires<std::is_integral<T>>>
61 explicit gdb_mpz (T src)
62 {
63 mpz_init (m_val);
64 set (src);
65 }
66
67 explicit gdb_mpz (gdb_mpz &&from)
68 {
69 mpz_init (m_val);
70 mpz_swap (m_val, from.m_val);
71 }
72
73
75 {
76 mpz_set (m_val, from.m_val);
77 return *this;
78 }
79
81 {
82 mpz_swap (m_val, other.m_val);
83 return *this;
84 }
85
86 template<typename T, typename = gdb::Requires<std::is_integral<T>>>
88 {
89 set (src);
90 return *this;
91 }
92
94 {
95 mpz_set_ui (m_val, (unsigned long) src);
96 return *this;
97 }
98
99 /* Initialize this value from a string and a base. Returns true if
100 the string was parsed successfully, false otherwise. */
101 bool set (const char *str, int base)
102 {
103 return mpz_set_str (m_val, str, base) != -1;
104 }
105
106 /* Return a new value that is BASE**EXP. */
107 static gdb_mpz pow (unsigned long base, unsigned long exp)
108 {
109 gdb_mpz result;
110 mpz_ui_pow_ui (result.m_val, base, exp);
111 return result;
112 }
113
114 /* Return a new value that is this value raised to EXP. */
115 gdb_mpz pow (unsigned long exp) const
116 {
117 gdb_mpz result;
118 mpz_pow_ui (result.m_val, m_val, exp);
119 return result;
120 }
121
122 /* Convert this value to an integer of the given type.
123
124 The return type can signed or unsigned, with no size restriction. */
125 template<typename T> T as_integer () const;
126
127 /* Convert this value to an integer of the given type. If this
128 value is too large, it is truncated.
129
130 The return type can signed or unsigned, with no size restriction. */
131 template<typename T> T as_integer_truncate () const;
132
133 /* Set VAL by importing the number stored in the byte array (BUF),
134 using the given BYTE_ORDER. The size of the data to read is
135 the byte array's size.
136
137 UNSIGNED_P indicates whether the number has an unsigned type. */
138 void read (gdb::array_view<const gdb_byte> buf, enum bfd_endian byte_order,
139 bool unsigned_p);
140
141 /* Write VAL into BUF as a number whose byte size is the size of BUF,
142 using the given BYTE_ORDER.
143
144 UNSIGNED_P indicates whether the number has an unsigned type. */
145 void write (gdb::array_view<gdb_byte> buf, enum bfd_endian byte_order,
146 bool unsigned_p) const
147 {
148 export_bits (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */,
149 unsigned_p, true /* safe */);
150 }
151
152 /* Like write, but truncates the value to the desired number of
153 bytes. */
154 void truncate (gdb::array_view<gdb_byte> buf, enum bfd_endian byte_order,
155 bool unsigned_p) const
156 {
157 export_bits (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */,
158 unsigned_p, false /* safe */);
159 }
160
161 /* Return a string containing VAL. */
162 std::string str () const { return gmp_string_printf ("%Zd", m_val); }
163
164 /* The destructor. */
165 ~gdb_mpz () { mpz_clear (m_val); }
166
167 /* Negate this value in place. */
168 void negate ()
169 {
170 mpz_neg (m_val, m_val);
171 }
172
173 /* Take the one's complement in place. */
175 { mpz_com (m_val, m_val); }
176
177 /* Mask this value to N bits, in place. */
178 void mask (unsigned n)
179 { mpz_tdiv_r_2exp (m_val, m_val, n); }
180
181 /* Return the sign of this value. This returns -1 for a negative
182 value, 0 if the value is 0, and 1 for a positive value. */
183 int sgn () const
184 { return mpz_sgn (m_val); }
185
186 explicit operator bool () const
187 { return sgn () != 0; }
188
189 gdb_mpz &operator*= (long other)
190 {
191 mpz_mul_si (m_val, m_val, other);
192 return *this;
193 }
194
195 gdb_mpz operator* (const gdb_mpz &other) const
196 {
197 gdb_mpz result;
198 mpz_mul (result.m_val, m_val, other.m_val);
199 return result;
200 }
201
202 gdb_mpz operator/ (const gdb_mpz &other) const
203 {
204 gdb_mpz result;
205 mpz_tdiv_q (result.m_val, m_val, other.m_val);
206 return result;
207 }
208
209 gdb_mpz operator% (const gdb_mpz &other) const
210 {
211 gdb_mpz result;
212 mpz_tdiv_r (result.m_val, m_val, other.m_val);
213 return result;
214 }
215
216 gdb_mpz &operator+= (unsigned long other)
217 {
218 mpz_add_ui (m_val, m_val, other);
219 return *this;
220 }
221
223 {
224 mpz_add (m_val, m_val, other.m_val);
225 return *this;
226 }
227
228 gdb_mpz operator+ (const gdb_mpz &other) const
229 {
230 gdb_mpz result;
231 mpz_add (result.m_val, m_val, other.m_val);
232 return result;
233 }
234
235 gdb_mpz &operator-= (unsigned long other)
236 {
237 mpz_sub_ui (m_val, m_val, other);
238 return *this;
239 }
240
242 {
243 mpz_sub (m_val, m_val, other.m_val);
244 return *this;
245 }
246
247 gdb_mpz operator- (const gdb_mpz &other) const
248 {
249 gdb_mpz result;
250 mpz_sub (result.m_val, m_val, other.m_val);
251 return result;
252 }
253
254 gdb_mpz &operator<<= (unsigned long nbits)
255 {
256 mpz_mul_2exp (m_val, m_val, nbits);
257 return *this;
258 }
259
260 gdb_mpz operator<< (unsigned long nbits) const
261 {
262 gdb_mpz result;
263 mpz_mul_2exp (result.m_val, m_val, nbits);
264 return result;
265 }
266
267 gdb_mpz operator>> (unsigned long nbits) const
268 {
269 gdb_mpz result;
270 mpz_tdiv_q_2exp (result.m_val, m_val, nbits);
271 return result;
272 }
273
274 gdb_mpz &operator>>= (unsigned long nbits)
275 {
276 mpz_tdiv_q_2exp (m_val, m_val, nbits);
277 return *this;
278 }
279
280 gdb_mpz operator& (const gdb_mpz &other) const
281 {
282 gdb_mpz result;
283 mpz_and (result.m_val, m_val, other.m_val);
284 return result;
285 }
286
287 gdb_mpz operator| (const gdb_mpz &other) const
288 {
289 gdb_mpz result;
290 mpz_ior (result.m_val, m_val, other.m_val);
291 return result;
292 }
293
294 gdb_mpz operator^ (const gdb_mpz &other) const
295 {
296 gdb_mpz result;
297 mpz_xor (result.m_val, m_val, other.m_val);
298 return result;
299 }
300
301 bool operator> (const gdb_mpz &other) const
302 {
303 return mpz_cmp (m_val, other.m_val) > 0;
304 }
305
306 bool operator>= (const gdb_mpz &other) const
307 {
308 return mpz_cmp (m_val, other.m_val) >= 0;
309 }
310
311 bool operator< (const gdb_mpz &other) const
312 {
313 return mpz_cmp (m_val, other.m_val) < 0;
314 }
315
316 bool operator<= (const gdb_mpz &other) const
317 {
318 return mpz_cmp (m_val, other.m_val) <= 0;
319 }
320
321 bool operator< (long other) const
322 {
323 return mpz_cmp_si (m_val, other) < 0;
324 }
325
326 /* We want an operator== that can handle all integer types. For
327 types that are 'long' or narrower, we can use a GMP function and
328 avoid boxing the RHS. But, because overloading based on integer
329 type is a pain in C++, we accept all such types here and check
330 the size in the body. */
331 template<typename T, typename = gdb::Requires<std::is_integral<T>>>
332 bool operator== (T other) const
333 {
334 if (std::is_signed<T>::value)
335 {
336 if (sizeof (T) <= sizeof (long))
337 return mpz_cmp_si (m_val, other) == 0;
338 }
339 else
340 {
341 if (sizeof (T) <= sizeof (unsigned long))
342 return mpz_cmp_ui (m_val, other) == 0;
343 }
344 return *this == gdb_mpz (other);
345 }
346
347 bool operator== (const gdb_mpz &other) const
348 {
349 return mpz_cmp (m_val, other.m_val) == 0;
350 }
351
352 bool operator!= (const gdb_mpz &other) const
353 {
354 return mpz_cmp (m_val, other.m_val) != 0;
355 }
356
357private:
358
359 /* Helper template for constructor and operator=. */
360 template<typename T> void set (T src);
361
362 /* Low-level function to export VAL into BUF as a number whose byte size
363 is the size of BUF.
364
365 If UNSIGNED_P is true, then export VAL into BUF as an unsigned value.
366 Otherwise, export it as a signed value.
367
368 The API is inspired from GMP's mpz_export, hence the naming and types
369 of the following parameter:
370 - ENDIAN should be:
371 . 1 for most significant byte first; or
372 . -1 for least significant byte first; or
373 . 0 for native endianness.
374
375 If SAFE is true, an error is raised if BUF is not large enough to
376 contain the value being exported. If SAFE is false, the value is
377 truncated to fit in BUF. */
378 void export_bits (gdb::array_view<gdb_byte> buf, int endian, bool unsigned_p,
379 bool safe) const;
380
381 friend struct gdb_mpq;
382 friend struct gdb_mpf;
383
384 mpz_t m_val;
385};
386
387/* A class to make it easier to use GMP's mpq_t values within GDB. */
388
390{
391 /* Constructors. */
392 gdb_mpq () { mpq_init (m_val); }
393
394 explicit gdb_mpq (const mpq_t &from_val)
395 {
396 mpq_init (m_val);
397 mpq_set (m_val, from_val);
398 }
399
400 gdb_mpq (const gdb_mpq &from)
401 {
402 mpq_init (m_val);
403 mpq_set (m_val, from.m_val);
404 }
405
406 explicit gdb_mpq (gdb_mpq &&from)
407 {
408 mpq_init (m_val);
409 mpq_swap (m_val, from.m_val);
410 }
411
412 gdb_mpq (const gdb_mpz &num, const gdb_mpz &denom)
413 {
414 mpq_init (m_val);
415 mpz_set (mpq_numref (m_val), num.m_val);
416 mpz_set (mpq_denref (m_val), denom.m_val);
417 mpq_canonicalize (m_val);
418 }
419
420 gdb_mpq (long num, long denom)
421 {
422 mpq_init (m_val);
423 mpq_set_si (m_val, num, denom);
424 mpq_canonicalize (m_val);
425 }
426
427 /* Copy assignment operator. */
429 {
430 mpq_set (m_val, from.m_val);
431 return *this;
432 }
433
435 {
436 mpq_swap (m_val, from.m_val);
437 return *this;
438 }
439
441 {
442 mpq_set_z (m_val, from.m_val);
443 return *this;
444 }
445
447 {
448 mpq_set_d (m_val, d);
449 return *this;
450 }
451
452 /* Return the sign of this value. This returns -1 for a negative
453 value, 0 if the value is 0, and 1 for a positive value. */
454 int sgn () const
455 { return mpq_sgn (m_val); }
456
457 gdb_mpq operator+ (const gdb_mpq &other) const
458 {
459 gdb_mpq result;
460 mpq_add (result.m_val, m_val, other.m_val);
461 return result;
462 }
463
464 gdb_mpq operator- (const gdb_mpq &other) const
465 {
466 gdb_mpq result;
467 mpq_sub (result.m_val, m_val, other.m_val);
468 return result;
469 }
470
471 gdb_mpq operator* (const gdb_mpq &other) const
472 {
473 gdb_mpq result;
474 mpq_mul (result.m_val, m_val, other.m_val);
475 return result;
476 }
477
478 gdb_mpq operator/ (const gdb_mpq &other) const
479 {
480 gdb_mpq result;
481 mpq_div (result.m_val, m_val, other.m_val);
482 return result;
483 }
484
486 {
487 mpq_mul (m_val, m_val, other.m_val);
488 return *this;
489 }
490
492 {
493 mpq_div (m_val, m_val, other.m_val);
494 return *this;
495 }
496
497 bool operator== (const gdb_mpq &other) const
498 {
499 return mpq_cmp (m_val, other.m_val) == 0;
500 }
501
502 bool operator< (const gdb_mpq &other) const
503 {
504 return mpq_cmp (m_val, other.m_val) < 0;
505 }
506
507 /* Return a string representing VAL as "<numerator> / <denominator>". */
508 std::string str () const { return gmp_string_printf ("%Qd", m_val); }
509
510 /* Return VAL rounded to the nearest integer. */
511 gdb_mpz get_rounded () const;
512
513 /* Return this value as an integer, rounded toward zero. */
515 {
516 gdb_mpz result;
517 mpz_tdiv_q (result.m_val, mpq_numref (m_val), mpq_denref (m_val));
518 return result;
519 }
520
521 /* Return this value converted to a host double. */
522 double as_double () const
523 { return mpq_get_d (m_val); }
524
525 /* Set VAL from the contents of the given byte array (BUF), which
526 contains the unscaled value of a fixed point type object.
527 The byte size of the data is the size of BUF.
528
529 BYTE_ORDER provides the byte_order to use when reading the data.
530
531 UNSIGNED_P indicates whether the number has an unsigned type.
532 SCALING_FACTOR is the scaling factor to apply after having
533 read the unscaled value from our buffer. */
534 void read_fixed_point (gdb::array_view<const gdb_byte> buf,
535 enum bfd_endian byte_order, bool unsigned_p,
536 const gdb_mpq &scaling_factor);
537
538 /* Write VAL into BUF as fixed point value following the given BYTE_ORDER.
539 The size of BUF is used as the length to write the value into.
540
541 UNSIGNED_P indicates whether the number has an unsigned type.
542 SCALING_FACTOR is the scaling factor to apply before writing
543 the unscaled value to our buffer. */
544 void write_fixed_point (gdb::array_view<gdb_byte> buf,
545 enum bfd_endian byte_order, bool unsigned_p,
546 const gdb_mpq &scaling_factor) const;
547
548 /* The destructor. */
549 ~gdb_mpq () { mpq_clear (m_val); }
550
551private:
552
553 friend struct gdb_mpf;
554
555 mpq_t m_val;
556};
557
558/* A class to make it easier to use GMP's mpf_t values within GDB.
559
560 Should MPFR become a required dependency, we should probably
561 drop this class in favor of using MPFR. */
562
564{
565 /* Constructors. */
566 gdb_mpf () { mpf_init (m_val); }
567
569
570 /* Set VAL from the contents of the given buffer (BUF), which
571 contains the unscaled value of a fixed point type object
572 with the given size (LEN) and byte order (BYTE_ORDER).
573
574 UNSIGNED_P indicates whether the number has an unsigned type.
575 SCALING_FACTOR is the scaling factor to apply after having
576 read the unscaled value from our buffer. */
577 void read_fixed_point (gdb::array_view<const gdb_byte> buf,
578 enum bfd_endian byte_order, bool unsigned_p,
579 const gdb_mpq &scaling_factor)
580 {
581 gdb_mpq tmp_q;
582
583 tmp_q.read_fixed_point (buf, byte_order, unsigned_p, scaling_factor);
584 mpf_set_q (m_val, tmp_q.m_val);
585 }
586
587 /* Convert this value to a string. FMT is the format to use, and
588 should have a single '%' substitution. */
589 std::string str (const char *fmt) const
590 { return gmp_string_printf (fmt, m_val); }
591
592 /* The destructor. */
593 ~gdb_mpf () { mpf_clear (m_val); }
594
595private:
596
597 mpf_t m_val;
598};
599
600/* See declaration above. */
601
602template<typename T>
603void
605{
606 mpz_import (m_val, 1 /* count */, -1 /* order */,
607 sizeof (T) /* size */, 0 /* endian (0 = native) */,
608 0 /* nails */, &src /* op */);
609 if (std::is_signed<T>::value && src < 0)
610 {
611 /* mpz_import does not handle the sign, so our value was imported
612 as an unsigned. Adjust that imported value so as to make it
613 the correct negative value. */
614 gdb_mpz neg_offset;
615
616 mpz_ui_pow_ui (neg_offset.m_val, 2, sizeof (T) * HOST_CHAR_BIT);
617 mpz_sub (m_val, m_val, neg_offset.m_val);
618 }
619}
620
621/* See declaration above. */
622
623template<typename T>
624T
626{
627 T result;
628
629 this->export_bits ({(gdb_byte *) &result, sizeof (result)},
630 0 /* endian (0 = native) */,
631 !std::is_signed<T>::value /* unsigned_p */,
632 true /* safe */);
633
634 return result;
635}
636
637/* See declaration above. */
638
639template<typename T>
640T
642{
643 T result;
644
645 this->export_bits ({(gdb_byte *) &result, sizeof (result)},
646 0 /* endian (0 = native) */,
647 !std::is_signed<T>::value /* unsigned_p */,
648 false /* safe */);
649
650 return result;
651}
652
653#endif
std::string gmp_string_printf(const char *fmt,...)
Definition gmp-utils.c:24
Definition 1.cc:26
mpf_t m_val
Definition gmp-utils.h:597
DISABLE_COPY_AND_ASSIGN(gdb_mpf)
std::string str(const char *fmt) const
Definition gmp-utils.h:589
void read_fixed_point(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order, bool unsigned_p, const gdb_mpq &scaling_factor)
Definition gmp-utils.h:577
void write_fixed_point(gdb::array_view< gdb_byte > buf, enum bfd_endian byte_order, bool unsigned_p, const gdb_mpq &scaling_factor) const
Definition gmp-utils.c:224
gdb_mpq(const mpq_t &from_val)
Definition gmp-utils.h:394
gdb_mpq & operator*=(const gdb_mpq &other)
Definition gmp-utils.h:485
mpq_t m_val
Definition gmp-utils.h:555
gdb_mpq(const gdb_mpz &num, const gdb_mpz &denom)
Definition gmp-utils.h:412
bool operator==(const gdb_mpq &other) const
Definition gmp-utils.h:497
gdb_mpq & operator/=(const gdb_mpq &other)
Definition gmp-utils.h:491
bool operator<(const gdb_mpq &other) const
Definition gmp-utils.h:502
int sgn() const
Definition gmp-utils.h:454
gdb_mpq(const gdb_mpq &from)
Definition gmp-utils.h:400
double as_double() const
Definition gmp-utils.h:522
gdb_mpq operator/(const gdb_mpq &other) const
Definition gmp-utils.h:478
gdb_mpq & operator=(const gdb_mpq &from)
Definition gmp-utils.h:428
gdb_mpq(long num, long denom)
Definition gmp-utils.h:420
gdb_mpq(gdb_mpq &&from)
Definition gmp-utils.h:406
gdb_mpq operator-(const gdb_mpq &other) const
Definition gmp-utils.h:464
gdb_mpq operator+(const gdb_mpq &other) const
Definition gmp-utils.h:457
void read_fixed_point(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order, bool unsigned_p, const gdb_mpq &scaling_factor)
Definition gmp-utils.c:210
gdb_mpz get_rounded() const
Definition gmp-utils.c:177
gdb_mpz as_integer() const
Definition gmp-utils.h:514
gdb_mpq operator*(const gdb_mpq &other) const
Definition gmp-utils.h:471
std::string str() const
Definition gmp-utils.h:508
gdb_mpz operator&(const gdb_mpz &other) const
Definition gmp-utils.h:280
void mask(unsigned n)
Definition gmp-utils.h:178
std::string str() const
Definition gmp-utils.h:162
T as_integer_truncate() const
Definition gmp-utils.h:641
gdb_mpz operator%(const gdb_mpz &other) const
Definition gmp-utils.h:209
gdb_mpz operator+(const gdb_mpz &other) const
Definition gmp-utils.h:228
gdb_mpz operator*(const gdb_mpz &other) const
Definition gmp-utils.h:195
void negate()
Definition gmp-utils.h:168
gdb_mpz operator^(const gdb_mpz &other) const
Definition gmp-utils.h:294
gdb_mpz()
Definition gmp-utils.h:42
void read(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order, bool unsigned_p)
Definition gmp-utils.c:46
gdb_mpz(gdb_mpz &&from)
Definition gmp-utils.h:67
void write(gdb::array_view< gdb_byte > buf, enum bfd_endian byte_order, bool unsigned_p) const
Definition gmp-utils.h:145
int sgn() const
Definition gmp-utils.h:183
gdb_mpz operator-(const gdb_mpz &other) const
Definition gmp-utils.h:247
gdb_mpz(const mpz_t &from_val)
Definition gmp-utils.h:44
static gdb_mpz pow(unsigned long base, unsigned long exp)
Definition gmp-utils.h:107
gdb_mpz operator|(const gdb_mpz &other) const
Definition gmp-utils.h:287
gdb_mpz pow(unsigned long exp) const
Definition gmp-utils.h:115
void truncate(gdb::array_view< gdb_byte > buf, enum bfd_endian byte_order, bool unsigned_p) const
Definition gmp-utils.h:154
gdb_mpz operator/(const gdb_mpz &other) const
Definition gmp-utils.h:202
gdb_mpz & operator>>=(unsigned long nbits)
Definition gmp-utils.h:274
bool operator<=(const gdb_mpz &other) const
Definition gmp-utils.h:316
bool operator==(T other) const
Definition gmp-utils.h:332
T as_integer() const
Definition gmp-utils.h:625
bool operator>(const gdb_mpz &other) const
Definition gmp-utils.h:301
bool operator<(const gdb_mpz &other) const
Definition gmp-utils.h:311
mpz_t m_val
Definition gmp-utils.h:384
void complement()
Definition gmp-utils.h:174
gdb_mpz operator>>(unsigned long nbits) const
Definition gmp-utils.h:267
gdb_mpz & operator+=(unsigned long other)
Definition gmp-utils.h:216
bool set(const char *str, int base)
Definition gmp-utils.h:101
gdb_mpz & operator=(const gdb_mpz &from)
Definition gmp-utils.h:74
gdb_mpz(const gdb_mpz &from)
Definition gmp-utils.h:50
gdb_mpz operator<<(unsigned long nbits) const
Definition gmp-utils.h:260
gdb_mpz & operator-=(unsigned long other)
Definition gmp-utils.h:235
bool operator>=(const gdb_mpz &other) const
Definition gmp-utils.h:306
bool operator!=(const gdb_mpz &other) const
Definition gmp-utils.h:352
void export_bits(gdb::array_view< gdb_byte > buf, int endian, bool unsigned_p, bool safe) const
Definition gmp-utils.c:69
gdb_mpz & operator<<=(unsigned long nbits)
Definition gmp-utils.h:254
gdb_mpz(T src)
Definition gmp-utils.h:61
gdb_mpz & operator*=(long other)
Definition gmp-utils.h:189