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#else
188#define VECTYPE unsigned long
189#define SPLAT(p) (*(p) * (~0UL / 255))
190#define ALL_EQ(v1, v2) ((v1) == (v2))
191#define VEC_OR(v1, v2) ((v1) | (v2))
192#endif
193
194#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8
195
196static bool
197can_use_buffer_find_nonzero_offset_inner(const void *buf, size_t len)
198{
199 return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
200 * sizeof(VECTYPE)) == 0
201 && ((uintptr_t) buf) % sizeof(VECTYPE) == 0);
202}
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224static size_t buffer_find_nonzero_offset_inner(const void *buf, size_t len)
225{
226 const VECTYPE *p = buf;
227 const VECTYPE zero = (VECTYPE){0};
228 size_t i;
229
230 assert(can_use_buffer_find_nonzero_offset_inner(buf, len));
231
232 if (!len) {
233 return 0;
234 }
235
236 for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
237 if (!ALL_EQ(p[i], zero)) {
238 return i * sizeof(VECTYPE);
239 }
240 }
241
242 for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
243 i < len / sizeof(VECTYPE);
244 i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
245 VECTYPE tmp0 = VEC_OR(p[i + 0], p[i + 1]);
246 VECTYPE tmp1 = VEC_OR(p[i + 2], p[i + 3]);
247 VECTYPE tmp2 = VEC_OR(p[i + 4], p[i + 5]);
248 VECTYPE tmp3 = VEC_OR(p[i + 6], p[i + 7]);
249 VECTYPE tmp01 = VEC_OR(tmp0, tmp1);
250 VECTYPE tmp23 = VEC_OR(tmp2, tmp3);
251 if (!ALL_EQ(VEC_OR(tmp01, tmp23), zero)) {
252 break;
253 }
254 }
255
256 return i * sizeof(VECTYPE);
257}
258
259
260
261
262
263
264
265#if defined CONFIG_AVX2_OPT && QEMU_GNUC_PREREQ(4, 9)
266#pragma GCC push_options
267#pragma GCC target("avx2")
268#include <cpuid.h>
269#include <immintrin.h>
270
271#define AVX2_VECTYPE __m256i
272#define AVX2_SPLAT(p) _mm256_set1_epi8(*(p))
273#define AVX2_ALL_EQ(v1, v2) \
274 (_mm256_movemask_epi8(_mm256_cmpeq_epi8(v1, v2)) == 0xFFFFFFFF)
275#define AVX2_VEC_OR(v1, v2) (_mm256_or_si256(v1, v2))
276
277static bool
278can_use_buffer_find_nonzero_offset_avx2(const void *buf, size_t len)
279{
280 return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
281 * sizeof(AVX2_VECTYPE)) == 0
282 && ((uintptr_t) buf) % sizeof(AVX2_VECTYPE) == 0);
283}
284
285static size_t buffer_find_nonzero_offset_avx2(const void *buf, size_t len)
286{
287 const AVX2_VECTYPE *p = buf;
288 const AVX2_VECTYPE zero = (AVX2_VECTYPE){0};
289 size_t i;
290
291 assert(can_use_buffer_find_nonzero_offset_avx2(buf, len));
292
293 if (!len) {
294 return 0;
295 }
296
297 for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
298 if (!AVX2_ALL_EQ(p[i], zero)) {
299 return i * sizeof(AVX2_VECTYPE);
300 }
301 }
302
303 for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
304 i < len / sizeof(AVX2_VECTYPE);
305 i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
306 AVX2_VECTYPE tmp0 = AVX2_VEC_OR(p[i + 0], p[i + 1]);
307 AVX2_VECTYPE tmp1 = AVX2_VEC_OR(p[i + 2], p[i + 3]);
308 AVX2_VECTYPE tmp2 = AVX2_VEC_OR(p[i + 4], p[i + 5]);
309 AVX2_VECTYPE tmp3 = AVX2_VEC_OR(p[i + 6], p[i + 7]);
310 AVX2_VECTYPE tmp01 = AVX2_VEC_OR(tmp0, tmp1);
311 AVX2_VECTYPE tmp23 = AVX2_VEC_OR(tmp2, tmp3);
312 if (!AVX2_ALL_EQ(AVX2_VEC_OR(tmp01, tmp23), zero)) {
313 break;
314 }
315 }
316
317 return i * sizeof(AVX2_VECTYPE);
318}
319
320static bool avx2_support(void)
321{
322 int a, b, c, d;
323
324 if (__get_cpuid_max(0, NULL) < 7) {
325 return false;
326 }
327
328 __cpuid_count(7, 0, a, b, c, d);
329
330 return b & bit_AVX2;
331}
332
333bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len) \
334 __attribute__ ((ifunc("can_use_buffer_find_nonzero_offset_ifunc")));
335size_t buffer_find_nonzero_offset(const void *buf, size_t len) \
336 __attribute__ ((ifunc("buffer_find_nonzero_offset_ifunc")));
337
338static void *buffer_find_nonzero_offset_ifunc(void)
339{
340 typeof(buffer_find_nonzero_offset) *func = (avx2_support()) ?
341 buffer_find_nonzero_offset_avx2 : buffer_find_nonzero_offset_inner;
342
343 return func;
344}
345
346static void *can_use_buffer_find_nonzero_offset_ifunc(void)
347{
348 typeof(can_use_buffer_find_nonzero_offset) *func = (avx2_support()) ?
349 can_use_buffer_find_nonzero_offset_avx2 :
350 can_use_buffer_find_nonzero_offset_inner;
351
352 return func;
353}
354#pragma GCC pop_options
355#else
356bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len)
357{
358 return can_use_buffer_find_nonzero_offset_inner(buf, len);
359}
360
361size_t buffer_find_nonzero_offset(const void *buf, size_t len)
362{
363 return buffer_find_nonzero_offset_inner(buf, len);
364}
365#endif
366
367
368
369
370
371
372
373bool buffer_is_zero(const void *buf, size_t len)
374{
375
376
377
378
379
380
381 size_t i;
382 long d0, d1, d2, d3;
383 const long * const data = buf;
384
385
386 if (can_use_buffer_find_nonzero_offset(buf, len)) {
387 return buffer_find_nonzero_offset(buf, len) == len;
388 }
389
390 assert(len % (4 * sizeof(long)) == 0);
391 len /= sizeof(long);
392
393 for (i = 0; i < len; i += 4) {
394 d0 = data[i + 0];
395 d1 = data[i + 1];
396 d2 = data[i + 2];
397 d3 = data[i + 3];
398
399 if (d0 || d1 || d2 || d3) {
400 return false;
401 }
402 }
403
404 return true;
405}
406
407#ifndef _WIN32
408
409int fcntl_setfl(int fd, int flag)
410{
411 int flags;
412
413 flags = fcntl(fd, F_GETFL);
414 if (flags == -1)
415 return -errno;
416
417 if (fcntl(fd, F_SETFL, flags | flag) == -1)
418 return -errno;
419
420 return 0;
421}
422#endif
423
424static int64_t suffix_mul(char suffix, int64_t unit)
425{
426 switch (qemu_toupper(suffix)) {
427 case QEMU_STRTOSZ_DEFSUFFIX_B:
428 return 1;
429 case QEMU_STRTOSZ_DEFSUFFIX_KB:
430 return unit;
431 case QEMU_STRTOSZ_DEFSUFFIX_MB:
432 return unit * unit;
433 case QEMU_STRTOSZ_DEFSUFFIX_GB:
434 return unit * unit * unit;
435 case QEMU_STRTOSZ_DEFSUFFIX_TB:
436 return unit * unit * unit * unit;
437 case QEMU_STRTOSZ_DEFSUFFIX_PB:
438 return unit * unit * unit * unit * unit;
439 case QEMU_STRTOSZ_DEFSUFFIX_EB:
440 return unit * unit * unit * unit * unit * unit;
441 }
442 return -1;
443}
444
445
446
447
448
449
450
451int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
452 const char default_suffix, int64_t unit)
453{
454 int64_t retval = -EINVAL;
455 char *endptr;
456 unsigned char c;
457 int mul_required = 0;
458 double val, mul, integral, fraction;
459
460 errno = 0;
461 val = strtod(nptr, &endptr);
462 if (isnan(val) || endptr == nptr || errno != 0) {
463 goto fail;
464 }
465 fraction = modf(val, &integral);
466 if (fraction != 0) {
467 mul_required = 1;
468 }
469 c = *endptr;
470 mul = suffix_mul(c, unit);
471 if (mul >= 0) {
472 endptr++;
473 } else {
474 mul = suffix_mul(default_suffix, unit);
475 assert(mul >= 0);
476 }
477 if (mul == 1 && mul_required) {
478 goto fail;
479 }
480 if ((val * mul >= INT64_MAX) || val < 0) {
481 retval = -ERANGE;
482 goto fail;
483 }
484 retval = val * mul;
485
486fail:
487 if (end) {
488 *end = endptr;
489 }
490
491 return retval;
492}
493
494int64_t qemu_strtosz_suffix(const char *nptr, char **end,
495 const char default_suffix)
496{
497 return qemu_strtosz_suffix_unit(nptr, end, default_suffix, 1024);
498}
499
500int64_t qemu_strtosz(const char *nptr, char **end)
501{
502 return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
503}
504
505
506
507
508static int check_strtox_error(const char *p, char *endptr, const char **next,
509 int err)
510{
511
512
513
514 if (err == 0 && endptr == p) {
515 err = EINVAL;
516 }
517 if (!next && *endptr) {
518 return -EINVAL;
519 }
520 if (next) {
521 *next = endptr;
522 }
523 return -err;
524}
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
552int qemu_strtol(const char *nptr, const char **endptr, int base,
553 long *result)
554{
555 char *p;
556 int err = 0;
557 if (!nptr) {
558 if (endptr) {
559 *endptr = nptr;
560 }
561 err = -EINVAL;
562 } else {
563 errno = 0;
564 *result = strtol(nptr, &p, base);
565 err = check_strtox_error(nptr, p, endptr, errno);
566 }
567 return err;
568}
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583int qemu_strtoul(const char *nptr, const char **endptr, int base,
584 unsigned long *result)
585{
586 char *p;
587 int err = 0;
588 if (!nptr) {
589 if (endptr) {
590 *endptr = nptr;
591 }
592 err = -EINVAL;
593 } else {
594 errno = 0;
595 *result = strtoul(nptr, &p, base);
596
597 if (errno == ERANGE) {
598 *result = -1;
599 }
600 err = check_strtox_error(nptr, p, endptr, errno);
601 }
602 return err;
603}
604
605
606
607
608
609
610int qemu_strtoll(const char *nptr, const char **endptr, int base,
611 int64_t *result)
612{
613 char *p;
614 int err = 0;
615 if (!nptr) {
616 if (endptr) {
617 *endptr = nptr;
618 }
619 err = -EINVAL;
620 } else {
621 errno = 0;
622 *result = strtoll(nptr, &p, base);
623 err = check_strtox_error(nptr, p, endptr, errno);
624 }
625 return err;
626}
627
628
629
630
631
632
633int qemu_strtoull(const char *nptr, const char **endptr, int base,
634 uint64_t *result)
635{
636 char *p;
637 int err = 0;
638 if (!nptr) {
639 if (endptr) {
640 *endptr = nptr;
641 }
642 err = -EINVAL;
643 } else {
644 errno = 0;
645 *result = strtoull(nptr, &p, base);
646
647 if (errno == ERANGE) {
648 *result = -1;
649 }
650 err = check_strtox_error(nptr, p, endptr, errno);
651 }
652 return err;
653}
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
683int parse_uint(const char *s, unsigned long long *value, char **endptr,
684 int base)
685{
686 int r = 0;
687 char *endp = (char *)s;
688 unsigned long long val = 0;
689
690 if (!s) {
691 r = -EINVAL;
692 goto out;
693 }
694
695 errno = 0;
696 val = strtoull(s, &endp, base);
697 if (errno) {
698 r = -errno;
699 goto out;
700 }
701
702 if (endp == s) {
703 r = -EINVAL;
704 goto out;
705 }
706
707
708 while (isspace((unsigned char)*s)) {
709 s++;
710 }
711 if (*s == '-') {
712 val = 0;
713 r = -ERANGE;
714 goto out;
715 }
716
717out:
718 *value = val;
719 *endptr = endp;
720 return r;
721}
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737int parse_uint_full(const char *s, unsigned long long *value, int base)
738{
739 char *endp;
740 int r;
741
742 r = parse_uint(s, value, &endp, base);
743 if (r < 0) {
744 return r;
745 }
746 if (*endp) {
747 *value = 0;
748 return -EINVAL;
749 }
750
751 return 0;
752}
753
754int qemu_parse_fd(const char *param)
755{
756 long fd;
757 char *endptr;
758
759 errno = 0;
760 fd = strtol(param, &endptr, 10);
761 if (param == endptr ||
762 errno != 0 ||
763 *endptr != '\0' ||
764 fd < 0 ||
765 fd > INT_MAX ) {
766 return -1;
767 }
768 return fd;
769}
770
771
772
773
774
775int uleb128_encode_small(uint8_t *out, uint32_t n)
776{
777 g_assert(n <= 0x3fff);
778 if (n < 0x80) {
779 *out++ = n;
780 return 1;
781 } else {
782 *out++ = (n & 0x7f) | 0x80;
783 *out++ = n >> 7;
784 return 2;
785 }
786}
787
788int uleb128_decode_small(const uint8_t *in, uint32_t *n)
789{
790 if (!(*in & 0x80)) {
791 *n = *in++;
792 return 1;
793 } else {
794 *n = *in++ & 0x7f;
795
796 if (*in & 0x80) {
797 return -1;
798 }
799 *n |= *in++ << 7;
800 return 2;
801 }
802}
803
804
805
806
807int parse_debug_env(const char *name, int max, int initial)
808{
809 char *debug_env = getenv(name);
810 char *inv = NULL;
811 long debug;
812
813 if (!debug_env) {
814 return initial;
815 }
816 errno = 0;
817 debug = strtol(debug_env, &inv, 10);
818 if (inv == debug_env) {
819 return initial;
820 }
821 if (debug < 0 || debug > max || errno != 0) {
822 fprintf(stderr, "warning: %s not in [0, %d]", name, max);
823 return initial;
824 }
825 return debug;
826}
827
828
829
830
831const char *qemu_ether_ntoa(const MACAddr *mac)
832{
833 static char ret[18];
834
835 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
836 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
837
838 return ret;
839}
840