Browse Source

Introduce next_setqual_scno (needed for gdbserver backend)

During initialisation, gdbserver backend enumerates all the syscall
numbers enabled for tracing and asks GDB server to stop only on the
specified syscall numbers. Since number_set interface is now opaque,
we provide an ability to enumerate all the syscall numbers that are
enabled.

* defs.h (next_set_qual_scno): New declaration.
* number_set.h (next_set_bit_in_set_array): Likewise.
* filter_qualify.c (next_set_qual_scno): Implement it.
* number_set.c (next_set_bit_in_set_array): Likewise.
Eugene Syromiatnikov 2 years ago
parent
commit
a36ae4e402
4 changed files with 78 additions and 0 deletions
  1. 2
    0
      defs.h
  2. 32
    0
      filter_qualify.c
  3. 39
    0
      number_set.c
  4. 5
    0
      number_set.h

+ 2
- 0
defs.h View File

@@ -972,6 +972,8 @@ extern void print_ifindex(unsigned int);
972 972
 
973 973
 extern void print_bpf_filter_code(const uint16_t code, bool extended);
974 974
 
975
+extern unsigned int next_set_qual_scno(const unsigned int scno,
976
+				       unsigned qual_flg);
975 977
 extern void qualify(const char *);
976 978
 extern unsigned int qual_flags(const unsigned int);
977 979
 

+ 32
- 0
filter_qualify.c View File

@@ -467,3 +467,35 @@ qual_flags(const unsigned int scno)
467 467
 		| (is_number_in_set_array(scno, inject_set, current_personality)
468 468
 		   ? QUAL_INJECT : 0);
469 469
 }
470
+
471
+unsigned int
472
+next_set_qual_scno(const unsigned int scno, unsigned qual_flg)
473
+{
474
+	static const struct qual_set {
475
+		unsigned qual;
476
+		struct number_set ** const set;
477
+	} sets[] = {
478
+		{ QUAL_TRACE,   &trace_set },
479
+		{ QUAL_ABBREV,  &abbrev_set },
480
+		{ QUAL_VERBOSE, &verbose_set },
481
+		{ QUAL_RAW,     &raw_set },
482
+		{ QUAL_INJECT,  &inject_set },
483
+		{ 0,            NULL }
484
+	};
485
+
486
+	const struct qual_set *pos = sets;
487
+	unsigned res = nsyscalls;
488
+	unsigned ret;
489
+
490
+	while (qual_flg && pos->qual) {
491
+		ret = next_set_bit_in_set_array(scno, *(pos->set),
492
+						current_personality,
493
+						nsyscalls);
494
+
495
+		res = MIN(res, ret);
496
+		qual_flg &= ~pos->qual;
497
+		pos++;
498
+	}
499
+
500
+	return res;
501
+}

+ 39
- 0
number_set.c View File

@@ -12,6 +12,7 @@
12 12
 #include <stdbool.h>
13 13
 #include <stdlib.h>
14 14
 #include <string.h>
15
+#include "macros.h"
15 16
 #include "number_set.h"
16 17
 #include "xmalloc.h"
17 18
 
@@ -105,6 +106,44 @@ invert_number_set_array(struct number_set *const set, const unsigned int nmemb)
105 106
 		set[i].not = !set[i].not;
106 107
 }
107 108
 
109
+/**
110
+ * Returns index of the next non-zero bit (starting at bit number) in number set
111
+ * or limit.
112
+ */
113
+unsigned int
114
+next_set_bit_in_set_array(unsigned int number,
115
+			  const struct number_set *const set,
116
+			  const unsigned int idx, const unsigned limit)
117
+{
118
+	unsigned pos;
119
+	unsigned limit_slots = MIN(set[idx].nslots,
120
+				   (limit + BITS_PER_SLOT - 1) / BITS_PER_SLOT);
121
+	number_slot_t bitmask;
122
+	number_slot_t cur_slot;
123
+
124
+
125
+	for (pos = number / BITS_PER_SLOT; pos < limit_slots; pos++) {
126
+		cur_slot = set[idx].vec[pos] ^ (-1U * set[idx].not);
127
+
128
+		if (cur_slot == 0) {
129
+			number = (number + BITS_PER_SLOT) & (-BITS_PER_SLOT);
130
+			continue;
131
+		}
132
+		bitmask = 1 << (number & (BITS_PER_SLOT - 1));
133
+		for (;;) {
134
+			if (cur_slot & bitmask)
135
+				return MIN(number, limit);
136
+			number++;
137
+			bitmask <<= 1;
138
+			/* This check *can't be* optimized out: */
139
+			if (bitmask == 0)
140
+				break;
141
+		}
142
+	}
143
+
144
+	return limit;
145
+}
146
+
108 147
 struct number_set *
109 148
 alloc_number_set_array(const unsigned int nmemb)
110 149
 {

+ 5
- 0
number_set.h View File

@@ -33,6 +33,11 @@ clear_number_set_array(struct number_set *, unsigned int nmemb);
33 33
 extern void
34 34
 invert_number_set_array(struct number_set *, unsigned int nmemb);
35 35
 
36
+extern unsigned int
37
+next_set_bit_in_set_array(unsigned int number,
38
+			  const struct number_set * const set,
39
+			  const unsigned int idx, const unsigned limit);
40
+
36 41
 extern struct number_set *
37 42
 alloc_number_set_array(unsigned int nmemb) ATTRIBUTE_MALLOC;
38 43
 

Loading…
Cancel
Save