1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25#include "qemu-common.h"
26#include "qemu/host-utils.h"
27#include <math.h>
28
29#include "qemu/sockets.h"
30#include "qemu/iov.h"
31#include "net/net.h"
32#include "qemu/cutils.h"
33
34void strpadcpy(char *buf, int buf_size, const char *str, char pad)
35{
36 int len = qemu_strnlen(str, buf_size);
37 memcpy(buf, str, len);
38 memset(buf + len, pad, buf_size - len);
39}
40
41void pstrcpy(char *buf, int buf_size, const char *str)
42{
43 int c;
44 char *q = buf;
45
46 if (buf_size <= 0)
47 return;
48
49 for(;;) {
50 c = *str++;
51 if (c == 0 || q >= buf + buf_size - 1)
52 break;
53 *q++ = c;
54 }
55 *q = '\0';
56}
57
58
59char *pstrcat(char *buf, int buf_size, const char *s)
60{
61 int len;
62 len = strlen(buf);
63 if (len < buf_size)
64 pstrcpy(buf + len, buf_size - len, s);
65 return buf;
66}
67
68int strstart(const char *str, const char *val, const char **ptr)
69{
70 const char *p, *q;
71 p = str;
72 q = val;
73 while (*q != '\0') {
74 if (*p != *q)
75 return 0;
76 p++;
77 q++;
78 }
79 if (ptr)
80 *ptr = p;
81 return 1;
82}
83
84int stristart(const char *str, const char *val, const char **ptr)
85{
86 const char *p, *q;
87 p = str;
88 q = val;
89 while (*q != '\0') {
90 if (qemu_toupper(*p) != qemu_toupper(*q))
91 return 0;
92 p++;
93 q++;
94 }
95 if (ptr)
96 *ptr = p;
97 return 1;
98}
99
100
101int qemu_strnlen(const char *s, int max_len)
102{
103 int i;
104
105 for(i = 0; i < max_len; i++) {
106 if (s[i] == '\0') {
107 break;
108 }
109 }
110 return i;
111}
112
113char *qemu_strsep(char **input, const char *delim)
114{
115 char *result = *input;
116 if (result != NULL) {
117 char *p;
118
119 for (p = result; *p != '\0'; p++) {
120 if (strchr(delim, *p)) {
121 break;
122 }
123 }
124 if (*p == '\0') {
125 *input = NULL;
126 } else {
127 *p = '\0';
128 *input = p + 1;
129 }
130 }
131 return result;
132}
133
134time_t mktimegm(struct tm *tm)
135{
136 time_t t;
137 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
138 if (m < 3) {
139 m += 12;
140 y--;
141 }
142 t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
143 y / 400 - 719469);
144 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
145 return t;
146}
147
148
149
150
151
152
153
154
155int qemu_fdatasync(int fd)
156{
157#ifdef CONFIG_FDATASYNC
158 return fdatasync(fd);
159#else
160 return fsync(fd);
161#endif
162}
163
164
165#ifdef __ALTIVEC__
166#include <altivec.h>
167
168
169
170
171#undef vector
172#undef pixel
173#undef bool
174#define VECTYPE __vector unsigned char
175#define SPLAT(p) vec_splat(vec_ld(0, p), 0)
176#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
177#define VEC_OR(v1, v2) ((v1) | (v2))
178
179
180#define bool _Bool
181#elif defined __SSE2__
182#include <emmintrin.h>
183#define VECTYPE __m128i
184#define SPLAT(p) _mm_set1_epi8(*(p))
185#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
186#define VEC_OR(v1, v2) (_mm_or_si128(v1, v2))
187#elif defined(__aarch64__)
188#include "arm_neon.h"
189#define VECTYPE uint64x2_t
190#define ALL_EQ(v1, v2) \
191 ((vgetq_lane_u64(v1, 0) == vgetq_lane_u64(v2, 0)) && \
192 (vgetq_lane_u64(v1, 1) == vgetq_lane_u64(v2, 1)))
193#define VEC_OR(v1, v2) ((v1) | (v2))
194#else
195#define VECTYPE unsigned long
196#define SPLAT(p) (*(p) * (~0UL / 255))
197#define ALL_EQ(v1, v2) ((v1) == (v2))
198#define VEC_OR(v1, v2) ((v1) | (v2))
199#endif
200
201#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8
202
203static bool
204can_use_buffer_find_nonzero_offset_inner(const void *buf, size_t len)
205{
206 return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
207 * sizeof(VECTYPE)) == 0
208 && ((uintptr_t) buf) % sizeof(VECTYPE) == 0);
209}
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231static size_t buffer_find_nonzero_offset_inner(const void *buf, size_t len)
232{
233 const VECTYPE *p = buf;
234 const VECTYPE zero = (VECTYPE){0};
235 size_t i;
236
237 assert(can_use_buffer_find_nonzero_offset_inner(buf, len));
238
239 if (!len) {
240 return 0;
241 }
242
243 for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
244 if (!ALL_EQ(p[i], zero)) {
245 return i * sizeof(VECTYPE);
246 }
247 }
248
249 for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
250 i < len / sizeof(VECTYPE);
251 i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
252 VECTYPE tmp0 = VEC_OR(p[i + 0], p[i + 1]);
253 VECTYPE tmp1 = VEC_OR(p[i + 2], p[i + 3]);
254 VECTYPE tmp2 = VEC_OR(p[i + 4], p[i + 5]);
255 VECTYPE tmp3 = VEC_OR(p[i + 6], p[i + 7]);
256 VECTYPE tmp01 = VEC_OR(tmp0, tmp1);
257 VECTYPE tmp23 = VEC_OR(tmp2, tmp3);
258 if (!ALL_EQ(VEC_OR(tmp01, tmp23), zero)) {
259 break;
260 }
261 }
262
263 return i * sizeof(VECTYPE);
264}
265
266#if defined CONFIG_AVX2_OPT
267#pragma GCC push_options
268#pragma GCC target("avx2")
269#include <cpuid.h>
270#include <immintrin.h>
271
272#define AVX2_VECTYPE __m256i
273#define AVX2_SPLAT(p) _mm256_set1_epi8(*(p))
274#define AVX2_ALL_EQ(v1, v2) \
275 (_mm256_movemask_epi8(_mm256_cmpeq_epi8(v1, v2)) == 0xFFFFFFFF)
276#define AVX2_VEC_OR(v1, v2) (_mm256_or_si256(v1, v2))
277
278static bool
279can_use_buffer_find_nonzero_offset_avx2(const void *buf, size_t len)
280{
281 return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
282 * sizeof(AVX2_VECTYPE)) == 0
283 && ((uintptr_t) buf) % sizeof(AVX2_VECTYPE) == 0);
284}
285
286static size_t buffer_find_nonzero_offset_avx2(const void *buf, size_t len)
287{
288 const AVX2_VECTYPE *p = buf;
289 const AVX2_VECTYPE zero = (AVX2_VECTYPE){0};
290 size_t i;
291
292 assert(can_use_buffer_find_nonzero_offset_avx2(buf, len));
293
294 if (!len) {
295 return 0;
296 }
297
298 for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
299 if (!AVX2_ALL_EQ(p[i], zero)) {
300 return i * sizeof(AVX2_VECTYPE);
301 }
302 }
303
304 for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
305 i < len / sizeof(AVX2_VECTYPE);
306 i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
307 AVX2_VECTYPE tmp0 = AVX2_VEC_OR(p[i + 0], p[i + 1]);
308 AVX2_VECTYPE tmp1 = AVX2_VEC_OR(p[i + 2], p[i + 3]);
309 AVX2_VECTYPE tmp2 = AVX2_VEC_OR(p[i + 4], p[i + 5]);
310 AVX2_VECTYPE tmp3 = AVX2_VEC_OR(p[i + 6], p[i + 7]);
311 AVX2_VECTYPE tmp01 = AVX2_VEC_OR(tmp0, tmp1);
312 AVX2_VECTYPE tmp23 = AVX2_VEC_OR(tmp2, tmp3);
313 if (!AVX2_ALL_EQ(AVX2_VEC_OR(tmp01, tmp23), zero)) {
314 break;
315 }
316 }
317
318 return i * sizeof(AVX2_VECTYPE);
319}
320
321static bool avx2_support(void)
322{
323 int a, b, c, d;
324
325 if (__get_cpuid_max(0, NULL) < 7) {
326 return false;
327 }
328
329 __cpuid_count(7, 0, a, b, c, d);
330
331 return b & bit_AVX2;
332}
333
334bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len) \
335 __attribute__ ((ifunc("can_use_buffer_find_nonzero_offset_ifunc")));
336size_t buffer_find_nonzero_offset(const void *buf, size_t len) \
337 __attribute__ ((ifunc("buffer_find_nonzero_offset_ifunc")));
338
339static void *buffer_find_nonzero_offset_ifunc(void)
340{
341 typeof(buffer_find_nonzero_offset) *func = (avx2_support()) ?
342 buffer_find_nonzero_offset_avx2 : buffer_find_nonzero_offset_inner;
343
344 return func;
345}
346
347static void *can_use_buffer_find_nonzero_offset_ifunc(void)
348{
349 typeof(can_use_buffer_find_nonzero_offset) *func = (avx2_support()) ?
350 can_use_buffer_find_nonzero_offset_avx2 :
351 can_use_buffer_find_nonzero_offset_inner;
352
353 return func;
354}
355#pragma GCC pop_options
356#else
357bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len)
358{
359 return can_use_buffer_find_nonzero_offset_inner(buf, len);
360}
361
362size_t buffer_find_nonzero_offset(const void *buf, size_t len)
363{
364 return buffer_find_nonzero_offset_inner(buf, len);
365}
366#endif
367
368
369
370
371
372
373
374bool buffer_is_zero(const void *buf, size_t len)
375{
376
377
378
379
380
381
382 size_t i;
383 long d0, d1, d2, d3;
384 const long * const data = buf;
385
386
387 if (can_use_buffer_find_nonzero_offset(buf, len)) {
388 return buffer_find_nonzero_offset(buf, len) == len;
389 }
390
391 assert(len % (4 * sizeof(long)) == 0);
392 len /= sizeof(long);
393
394 for (i = 0; i < len; i += 4) {
395 d0 = data[i + 0];
396 d1 = data[i + 1];
397 d2 = data[i + 2];
398 d3 = data[i + 3];
399
400 if (d0 || d1 || d2 || d3) {
401 return false;
402 }
403 }
404
405 return true;
406}
407
408#ifndef _WIN32
409
410int fcntl_setfl(int fd, int flag)
411{
412 int flags;
413
414 flags = fcntl(fd, F_GETFL);
415 if (flags == -1)
416 return -errno;
417
418 if (fcntl(fd, F_SETFL, flags | flag) == -1)
419 return -errno;
420
421 return 0;
422}
423#endif
424
425static int64_t suffix_mul(char suffix, int64_t unit)
426{
427 switch (qemu_toupper(suffix)) {
428 case QEMU_STRTOSZ_DEFSUFFIX_B:
429 return 1;
430 case QEMU_STRTOSZ_DEFSUFFIX_KB:
431 return unit;
432 case QEMU_STRTOSZ_DEFSUFFIX_MB:
433 return unit * unit;
434 case QEMU_STRTOSZ_DEFSUFFIX_GB:
435 return unit * unit * unit;
436 case QEMU_STRTOSZ_DEFSUFFIX_TB:
437 return unit * unit * unit * unit;
438 case QEMU_STRTOSZ_DEFSUFFIX_PB:
439 return unit * unit * unit * unit * unit;
440 case QEMU_STRTOSZ_DEFSUFFIX_EB:
441 return unit * unit * unit * unit * unit * unit;
442 }
443 return -1;
444}
445
446
447
448
449
450
451
452int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
453 const char default_suffix, int64_t unit)
454{
455 int64_t retval = -EINVAL;
456 char *endptr;
457 unsigned char c;
458 int mul_required = 0;
459 double val, mul, integral, fraction;
460
461 errno = 0;
462 val = strtod(nptr, &endptr);
463 if (isnan(val) || endptr == nptr || errno != 0) {
464 goto fail;
465 }
466 fraction = modf(val, &integral);
467 if (fraction != 0) {
468 mul_required = 1;
469 }
470 c = *endptr;
471 mul = suffix_mul(c, unit);
472 if (mul >= 0) {
473 endptr++;
474 } else {
475 mul = suffix_mul(default_suffix, unit);
476 assert(mul >= 0);
477 }
478 if (mul == 1 && mul_required) {
479 goto fail;
480 }
481 if ((val * mul >= INT64_MAX) || val < 0) {
482 retval = -ERANGE;
483 goto fail;
484 }
485 retval = val * mul;
486
487fail:
488 if (end) {
489 *end = endptr;
490 }
491
492 return retval;
493}
494
495int64_t qemu_strtosz_suffix(const char *nptr, char **end,
496 const char default_suffix)
497{
498 return qemu_strtosz_suffix_unit(nptr, end, default_suffix, 1024);
499}
500
501int64_t qemu_strtosz(const char *nptr, char **end)
502{
503 return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
504}
505
506
507
508
509static int check_strtox_error(const char *p, char *endptr, const char **next,
510 int err)
511{
512
513
514
515 if (err == 0 && endptr == p) {
516 err = EINVAL;
517 }
518 if (!next && *endptr) {
519 return -EINVAL;
520 }
521 if (next) {
522 *next = endptr;
523 }
524 return -err;
525}
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553int qemu_strtol(const char *nptr, const char **endptr, int base,
554 long *result)
555{
556 char *p;
557 int err = 0;
558 if (!nptr) {
559 if (endptr) {
560 *endptr = nptr;
561 }
562 err = -EINVAL;
563 } else {
564 errno = 0;
565 *result = strtol(nptr, &p, base);
566 err = check_strtox_error(nptr, p, endptr, errno);
567 }
568 return err;
569}
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584int qemu_strtoul(const char *nptr, const char **endptr, int base,
585 unsigned long *result)
586{
587 char *p;
588 int err = 0;
589 if (!nptr) {
590 if (endptr) {
591 *endptr = nptr;
592 }
593 err = -EINVAL;
594 } else {
595 errno = 0;
596 *result = strtoul(nptr, &p, base);
597
598 if (errno == ERANGE) {
599 *result = -1;
600 }
601 err = check_strtox_error(nptr, p, endptr, errno);
602 }
603 return err;
604}
605
606
607
608
609
610
611int qemu_strtoll(const char *nptr, const char **endptr, int base,
612 int64_t *result)
613{
614 char *p;
615 int err = 0;
616 if (!nptr) {
617 if (endptr) {
618 *endptr = nptr;
619 }
620 err = -EINVAL;
621 } else {
622 errno = 0;
623 *result = strtoll(nptr, &p, base);
624 err = check_strtox_error(nptr, p, endptr, errno);
625 }
626 return err;
627}
628
629
630
631
632
633
634int qemu_strtoull(const char *nptr, const char **endptr, int base,
635 uint64_t *result)
636{
637 char *p;
638 int err = 0;
639 if (!nptr) {
640 if (endptr) {
641 *endptr = nptr;
642 }
643 err = -EINVAL;
644 } else {
645 errno = 0;
646 *result = strtoull(nptr, &p, base);
647
648 if (errno == ERANGE) {
649 *result = -1;
650 }
651 err = check_strtox_error(nptr, p, endptr, errno);
652 }
653 return err;
654}
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684int parse_uint(const char *s, unsigned long long *value, char **endptr,
685 int base)
686{
687 int r = 0;
688 char *endp = (char *)s;
689 unsigned long long val = 0;
690
691 if (!s) {
692 r = -EINVAL;
693 goto out;
694 }
695
696 errno = 0;
697 val = strtoull(s, &endp, base);
698 if (errno) {
699 r = -errno;
700 goto out;
701 }
702
703 if (endp == s) {
704 r = -EINVAL;
705 goto out;
706 }
707
708
709 while (isspace((unsigned char)*s)) {
710 s++;
711 }
712 if (*s == '-') {
713 val = 0;
714 r = -ERANGE;
715 goto out;
716 }
717
718out:
719 *value = val;
720 *endptr = endp;
721 return r;
722}
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738int parse_uint_full(const char *s, unsigned long long *value, int base)
739{
740 char *endp;
741 int r;
742
743 r = parse_uint(s, value, &endp, base);
744 if (r < 0) {
745 return r;
746 }
747 if (*endp) {
748 *value = 0;
749 return -EINVAL;
750 }
751
752 return 0;
753}
754
755int qemu_parse_fd(const char *param)
756{
757 long fd;
758 char *endptr;
759
760 errno = 0;
761 fd = strtol(param, &endptr, 10);
762 if (param == endptr ||
763 errno != 0 ||
764 *endptr != '\0' ||
765 fd < 0 ||
766 fd > INT_MAX ) {
767 return -1;
768 }
769 return fd;
770}
771
772
773
774
775
776int uleb128_encode_small(uint8_t *out, uint32_t n)
777{
778 g_assert(n <= 0x3fff);
779 if (n < 0x80) {
780 *out++ = n;
781 return 1;
782 } else {
783 *out++ = (n & 0x7f) | 0x80;
784 *out++ = n >> 7;
785 return 2;
786 }
787}
788
789int uleb128_decode_small(const uint8_t *in, uint32_t *n)
790{
791 if (!(*in & 0x80)) {
792 *n = *in++;
793 return 1;
794 } else {
795 *n = *in++ & 0x7f;
796
797 if (*in & 0x80) {
798 return -1;
799 }
800 *n |= *in++ << 7;
801 return 2;
802 }
803}
804
805
806
807
808int parse_debug_env(const char *name, int max, int initial)
809{
810 char *debug_env = getenv(name);
811 char *inv = NULL;
812 long debug;
813
814 if (!debug_env) {
815 return initial;
816 }
817 errno = 0;
818 debug = strtol(debug_env, &inv, 10);
819 if (inv == debug_env) {
820 return initial;
821 }
822 if (debug < 0 || debug > max || errno != 0) {
823 fprintf(stderr, "warning: %s not in [0, %d]", name, max);
824 return initial;
825 }
826 return debug;
827}
828
829
830
831
832const char *qemu_ether_ntoa(const MACAddr *mac)
833{
834 static char ret[18];
835
836 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
837 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
838
839 return ret;
840}
841