[io-layer] add URLs for some ximian bug numbers in sockets.cs
[mono.git] / tools / sgen / sgen-grep-binprot.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <glib.h>
5
6 #define SGEN_BINARY_PROTOCOL
7 #define MONO_INTERNAL
8
9 #include <mono/metadata/sgen-protocol.h>
10
11 #define SGEN_PROTOCOL_EOF       255
12
13 static int
14 read_entry (FILE *in, void **data)
15 {
16         unsigned char type;
17         int size;
18
19         if (fread (&type, 1, 1, in) != 1)
20                 return SGEN_PROTOCOL_EOF;
21         switch (type) {
22         case SGEN_PROTOCOL_COLLECTION_BEGIN: size = sizeof (SGenProtocolCollection); break;
23         case SGEN_PROTOCOL_COLLECTION_END: size = sizeof (SGenProtocolCollection); break;
24         case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break;
25         case SGEN_PROTOCOL_ALLOC_PINNED: size = sizeof (SGenProtocolAlloc); break;
26         case SGEN_PROTOCOL_ALLOC_DEGRADED: size = sizeof (SGenProtocolAlloc); break;
27         case SGEN_PROTOCOL_COPY: size = sizeof (SGenProtocolCopy); break;
28         case SGEN_PROTOCOL_PIN: size = sizeof (SGenProtocolPin); break;
29         case SGEN_PROTOCOL_MARK: size = sizeof (SGenProtocolMark); break;
30         case SGEN_PROTOCOL_SCAN_BEGIN: size = sizeof (SGenProtocolScanBegin); break;
31         case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: size = sizeof (SGenProtocolScanVTypeBegin); break;
32         case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
33         case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
34         case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
35         case SGEN_PROTOCOL_CLEANUP: size = sizeof (SGenProtocolCleanup); break;
36         case SGEN_PROTOCOL_EMPTY: size = sizeof (SGenProtocolEmpty); break;
37         case SGEN_PROTOCOL_THREAD_SUSPEND: size = sizeof (SGenProtocolThreadSuspend); break;
38         case SGEN_PROTOCOL_THREAD_RESTART: size = sizeof (SGenProtocolThreadRestart); break;
39         case SGEN_PROTOCOL_THREAD_REGISTER: size = sizeof (SGenProtocolThreadRegister); break;
40         case SGEN_PROTOCOL_THREAD_UNREGISTER: size = sizeof (SGenProtocolThreadUnregister); break;
41         case SGEN_PROTOCOL_MISSING_REMSET: size = sizeof (SGenProtocolMissingRemset); break;
42         case SGEN_PROTOCOL_CARD_SCAN: size = sizeof (SGenProtocolCardScan); break;
43         case SGEN_PROTOCOL_CEMENT: size = sizeof (SGenProtocolCement); break;
44         case SGEN_PROTOCOL_CEMENT_RESET: size = 0; break;
45         case SGEN_PROTOCOL_DISLINK_UPDATE: size = sizeof (SGenProtocolDislinkUpdate); break;
46         default: assert (0);
47         }
48
49         if (size) {
50                 *data = malloc (size);
51                 if (fread (*data, size, 1, in) != 1)
52                         assert (0);
53         } else {
54                 *data = NULL;
55         }
56
57         return (int)type;
58 }
59
60 static void
61 print_entry (int type, void *data)
62 {
63         switch (type) {
64         case SGEN_PROTOCOL_COLLECTION_BEGIN: {
65                 SGenProtocolCollection *entry = data;
66                 printf ("collection begin %d generation %d\n", entry->index, entry->generation);
67                 break;
68         }
69         case SGEN_PROTOCOL_COLLECTION_END: {
70                 SGenProtocolCollection *entry = data;
71                 printf ("collection end %d generation %d\n", entry->index, entry->generation);
72                 break;
73         }
74         case SGEN_PROTOCOL_ALLOC: {
75                 SGenProtocolAlloc *entry = data;
76                 printf ("alloc obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
77                 break;
78         }
79         case SGEN_PROTOCOL_ALLOC_PINNED: {
80                 SGenProtocolAlloc *entry = data;
81                 printf ("alloc pinned obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
82                 break;
83         }
84         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
85                 SGenProtocolAlloc *entry = data;
86                 printf ("alloc degraded obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
87                 break;
88         }
89         case SGEN_PROTOCOL_COPY: {
90                 SGenProtocolCopy *entry = data;
91                 printf ("copy from %p to %p vtable %p size %d\n", entry->from, entry->to, entry->vtable, entry->size);
92                 break;
93         }
94         case SGEN_PROTOCOL_PIN: {
95                 SGenProtocolPin *entry = data;
96                 printf ("pin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
97                 break;
98         }
99         case SGEN_PROTOCOL_MARK: {
100                 SGenProtocolMark *entry = data;
101                 printf ("mark obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
102                 break;
103         }
104         case SGEN_PROTOCOL_SCAN_BEGIN: {
105                 SGenProtocolScanBegin *entry = data;
106                 printf ("scan_begin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
107                 break;
108         }
109         case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
110                 SGenProtocolScanVTypeBegin *entry = data;
111                 printf ("scan_vtype_begin obj %p size %d\n", entry->obj, entry->size);
112                 break;
113         }
114         case SGEN_PROTOCOL_WBARRIER: {
115                 SGenProtocolWBarrier *entry = data;
116                 printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
117                 break;
118         }
119         case SGEN_PROTOCOL_GLOBAL_REMSET: {
120                 SGenProtocolGlobalRemset *entry = data;
121                 printf ("global_remset ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
122                 break;
123         }
124         case SGEN_PROTOCOL_PTR_UPDATE: {
125                 SGenProtocolPtrUpdate *entry = data;
126                 printf ("ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n",
127                                 entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
128                 break;
129         }
130         case SGEN_PROTOCOL_CLEANUP: {
131                 SGenProtocolCleanup *entry = data;
132                 printf ("cleanup ptr %p vtable %p size %d\n", entry->ptr, entry->vtable, entry->size);
133                 break;
134         }
135         case SGEN_PROTOCOL_EMPTY: {
136                 SGenProtocolEmpty *entry = data;
137                 printf ("empty start %p size %d\n", entry->start, entry->size);
138                 break;
139         }
140         case SGEN_PROTOCOL_THREAD_SUSPEND: {
141                 SGenProtocolThreadSuspend *entry = data;
142                 printf ("thread_suspend thread %p ip %p\n", entry->thread, entry->stopped_ip);
143                 break;
144         }
145         case SGEN_PROTOCOL_THREAD_RESTART: {
146                 SGenProtocolThreadRestart *entry = data;
147                 printf ("thread_restart thread %p\n", entry->thread);
148                 break;
149         }
150         case SGEN_PROTOCOL_THREAD_REGISTER: {
151                 SGenProtocolThreadRegister *entry = data;
152                 printf ("thread_register thread %p\n", entry->thread);
153                 break;
154         }
155         case SGEN_PROTOCOL_THREAD_UNREGISTER: {
156                 SGenProtocolThreadUnregister *entry = data;
157                 printf ("thread_unregister thread %p\n", entry->thread);
158                 break;
159         }
160         case SGEN_PROTOCOL_MISSING_REMSET: {
161                 SGenProtocolMissingRemset *entry = data;
162                 printf ("missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n",
163                                 entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
164                 break;
165         }
166         case SGEN_PROTOCOL_CARD_SCAN: {
167                 SGenProtocolCardScan *entry = data;
168                 printf ("card_scan start %p size %d\n", entry->start, entry->size);
169                 break;
170         }
171         case SGEN_PROTOCOL_CEMENT: {
172                 SGenProtocolCement *entry = data;
173                 printf ("cement obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
174                 break;
175         }
176         case SGEN_PROTOCOL_CEMENT_RESET: {
177                 printf ("cement_reset\n");
178                 break;
179         }
180         case SGEN_PROTOCOL_DISLINK_UPDATE: {
181                 SGenProtocolDislinkUpdate *entry = data;
182                 printf ("dislink_update link %p obj %p", entry->link, entry->obj);
183                 if (entry->obj)
184                         printf (" track %d\n", entry->track);
185                 else
186                         printf ("\n");
187                 break;
188         }
189         default:
190                 assert (0);
191         }
192 }
193
194 static gboolean
195 matches_interval (gpointer ptr, gpointer start, int size)
196 {
197         return ptr >= start && (char*)ptr < (char*)start + size;
198 }
199
200 static gboolean
201 is_match (gpointer ptr, int type, void *data)
202 {
203         switch (type) {
204         case SGEN_PROTOCOL_COLLECTION_BEGIN:
205         case SGEN_PROTOCOL_COLLECTION_END:
206         case SGEN_PROTOCOL_THREAD_SUSPEND:
207         case SGEN_PROTOCOL_THREAD_RESTART:
208         case SGEN_PROTOCOL_THREAD_REGISTER:
209         case SGEN_PROTOCOL_THREAD_UNREGISTER:
210         case SGEN_PROTOCOL_CEMENT_RESET:
211                 return TRUE;
212         case SGEN_PROTOCOL_ALLOC:
213         case SGEN_PROTOCOL_ALLOC_PINNED:
214         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
215                 SGenProtocolAlloc *entry = data;
216                 return matches_interval (ptr, entry->obj, entry->size);
217         }
218         case SGEN_PROTOCOL_COPY: {
219                 SGenProtocolCopy *entry = data;
220                 return matches_interval (ptr, entry->from, entry->size) || matches_interval (ptr, entry->to, entry->size);
221         }
222         case SGEN_PROTOCOL_PIN: {
223                 SGenProtocolPin *entry = data;
224                 return matches_interval (ptr, entry->obj, entry->size);
225         }
226         case SGEN_PROTOCOL_MARK: {
227                 SGenProtocolMark *entry = data;
228                 return matches_interval (ptr, entry->obj, entry->size);
229         }
230         case SGEN_PROTOCOL_SCAN_BEGIN: {
231                 SGenProtocolScanBegin *entry = data;
232                 return matches_interval (ptr, entry->obj, entry->size);
233         }
234         case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
235                 SGenProtocolScanVTypeBegin *entry = data;
236                 return matches_interval (ptr, entry->obj, entry->size);
237         }
238         case SGEN_PROTOCOL_WBARRIER: {
239                 SGenProtocolWBarrier *entry = data;
240                 return ptr == entry->ptr || ptr == entry->value;
241         }
242         case SGEN_PROTOCOL_GLOBAL_REMSET: {
243                 SGenProtocolGlobalRemset *entry = data;
244                 return ptr == entry->ptr || ptr == entry->value;
245         }
246         case SGEN_PROTOCOL_PTR_UPDATE: {
247                 SGenProtocolPtrUpdate *entry = data;
248                 return ptr == entry->ptr ||
249                         matches_interval (ptr, entry->old_value, entry->size) ||
250                         matches_interval (ptr, entry->new_value, entry->size);
251         }
252         case SGEN_PROTOCOL_CLEANUP: {
253                 SGenProtocolCleanup *entry = data;
254                 return matches_interval (ptr, entry->ptr, entry->size);
255         }
256         case SGEN_PROTOCOL_EMPTY: {
257                 SGenProtocolEmpty *entry = data;
258                 return matches_interval (ptr, entry->start, entry->size);
259         }
260         case SGEN_PROTOCOL_MISSING_REMSET: {
261                 SGenProtocolMissingRemset *entry = data;
262                 return ptr == entry->obj || ptr == entry->value || ptr == (char*)entry->obj + entry->offset;
263         }
264         case SGEN_PROTOCOL_CARD_SCAN: {
265                 SGenProtocolCardScan *entry = data;
266                 return matches_interval (ptr, entry->start, entry->size);
267         }
268         case SGEN_PROTOCOL_CEMENT: {
269                 SGenProtocolCement *entry = data;
270                 return matches_interval (ptr, entry->obj, entry->size);
271         }
272         case SGEN_PROTOCOL_DISLINK_UPDATE: {
273                 SGenProtocolDislinkUpdate *entry = data;
274                 return ptr == entry->obj || ptr == entry->link;
275         }
276         default:
277                 assert (0);
278         }
279 }
280
281 int
282 main (int argc, char *argv[])
283 {
284         int type;
285         void *data;
286         int num_nums = argc - 1;
287         int i;
288         long nums [num_nums];
289
290         for (i = 0; i < num_nums; ++i)
291                 nums [i] = strtoul (argv [i + 1], NULL, 16);
292
293         while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
294                 gboolean match = FALSE;
295                 for (i = 0; i < num_nums; ++i) {
296                         if (is_match ((gpointer) nums [i], type, data)) {
297                                 match = TRUE;
298                                 break;
299                         }
300                 }
301                 if (match)
302                         print_entry (type, data);
303                 free (data);
304         }
305
306         return 0;
307 }