[xbuild] Fix bug #671700, resource naming in presence of "Link".
[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: size = sizeof (SGenProtocolCollection); break;
23         case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break;
24         case SGEN_PROTOCOL_ALLOC_PINNED: size = sizeof (SGenProtocolAlloc); break;
25         case SGEN_PROTOCOL_ALLOC_DEGRADED: size = sizeof (SGenProtocolAlloc); break;
26         case SGEN_PROTOCOL_COPY: size = sizeof (SGenProtocolCopy); break;
27         case SGEN_PROTOCOL_PIN: size = sizeof (SGenProtocolPin); break;
28         case SGEN_PROTOCOL_MARK: size = sizeof (SGenProtocolMark); break;
29         case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
30         case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
31         case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
32         case SGEN_PROTOCOL_CLEANUP: size = sizeof (SGenProtocolCleanup); break;
33         case SGEN_PROTOCOL_EMPTY: size = sizeof (SGenProtocolEmpty); break;
34         case SGEN_PROTOCOL_THREAD_RESTART: size = sizeof (SGenProtocolThreadRestart); break;
35         case SGEN_PROTOCOL_THREAD_REGISTER: size = sizeof (SGenProtocolThreadRegister); break;
36         case SGEN_PROTOCOL_THREAD_UNREGISTER: size = sizeof (SGenProtocolThreadUnregister); break;
37         case SGEN_PROTOCOL_MISSING_REMSET: size = sizeof (SGenProtocolMissingRemset); break;
38         default: assert (0);
39         }
40
41         *data = malloc (size);
42         if (fread (*data, size, 1, in) != 1)
43                 assert (0);
44
45         return (int)type;
46 }
47
48 static void
49 print_entry (int type, void *data)
50 {
51         switch (type) {
52         case SGEN_PROTOCOL_COLLECTION: {
53                 SGenProtocolCollection *entry = data;
54                 printf ("collection generation %d\n", entry->generation);
55                 break;
56         }
57         case SGEN_PROTOCOL_ALLOC: {
58                 SGenProtocolAlloc *entry = data;
59                 printf ("alloc obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
60                 break;
61         }
62         case SGEN_PROTOCOL_ALLOC_PINNED: {
63                 SGenProtocolAlloc *entry = data;
64                 printf ("alloc pinned obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
65                 break;
66         }
67         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
68                 SGenProtocolAlloc *entry = data;
69                 printf ("alloc degraded obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
70                 break;
71         }
72         case SGEN_PROTOCOL_COPY: {
73                 SGenProtocolCopy *entry = data;
74                 printf ("copy from %p to %p vtable %p size %d\n", entry->from, entry->to, entry->vtable, entry->size);
75                 break;
76         }
77         case SGEN_PROTOCOL_PIN: {
78                 SGenProtocolPin *entry = data;
79                 printf ("pin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
80                 break;
81         }
82         case SGEN_PROTOCOL_MARK: {
83                 SGenProtocolMark *entry = data;
84                 printf ("mark obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
85                 break;
86         }
87         case SGEN_PROTOCOL_WBARRIER: {
88                 SGenProtocolWBarrier *entry = data;
89                 printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
90                 break;
91         }
92         case SGEN_PROTOCOL_GLOBAL_REMSET: {
93                 SGenProtocolGlobalRemset *entry = data;
94                 printf ("global_remset ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
95                 break;
96         }
97         case SGEN_PROTOCOL_PTR_UPDATE: {
98                 SGenProtocolPtrUpdate *entry = data;
99                 printf ("ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n",
100                                 entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
101                 break;
102         }
103         case SGEN_PROTOCOL_CLEANUP: {
104                 SGenProtocolCleanup *entry = data;
105                 printf ("cleanup ptr %p vtable %p size %d\n", entry->ptr, entry->vtable, entry->size);
106                 break;
107         }
108         case SGEN_PROTOCOL_EMPTY: {
109                 SGenProtocolEmpty *entry = data;
110                 printf ("empty start %p size %d\n", entry->start, entry->size);
111                 break;
112         }
113         case SGEN_PROTOCOL_THREAD_RESTART: {
114                 SGenProtocolThreadRestart *entry = data;
115                 printf ("thread_restart thread %p\n", entry->thread);
116                 break;
117         }
118         case SGEN_PROTOCOL_THREAD_REGISTER: {
119                 SGenProtocolThreadRegister *entry = data;
120                 printf ("thread_register thread %p\n", entry->thread);
121                 break;
122         }
123         case SGEN_PROTOCOL_THREAD_UNREGISTER: {
124                 SGenProtocolThreadUnregister *entry = data;
125                 printf ("thread_unregister thread %p\n", entry->thread);
126                 break;
127         }
128         case SGEN_PROTOCOL_MISSING_REMSET: {
129                 SGenProtocolMissingRemset *entry = data;
130                 printf ("missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n",
131                                 entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
132                 break;
133         }
134         default:
135                 assert (0);
136         }
137 }
138
139 static gboolean
140 matches_interval (gpointer ptr, gpointer start, int size)
141 {
142         return ptr >= start && (char*)ptr < (char*)start + size;
143 }
144
145 static gboolean
146 is_match (gpointer ptr, int type, void *data)
147 {
148         switch (type) {
149         case SGEN_PROTOCOL_COLLECTION:
150         case SGEN_PROTOCOL_THREAD_RESTART:
151         case SGEN_PROTOCOL_THREAD_REGISTER:
152         case SGEN_PROTOCOL_THREAD_UNREGISTER:
153                 return TRUE;
154         case SGEN_PROTOCOL_ALLOC:
155         case SGEN_PROTOCOL_ALLOC_PINNED:
156         case SGEN_PROTOCOL_ALLOC_DEGRADED: {
157                 SGenProtocolAlloc *entry = data;
158                 return matches_interval (ptr, entry->obj, entry->size);
159         }
160         case SGEN_PROTOCOL_COPY: {
161                 SGenProtocolCopy *entry = data;
162                 return matches_interval (ptr, entry->from, entry->size) || matches_interval (ptr, entry->to, entry->size);
163         }
164         case SGEN_PROTOCOL_PIN: {
165                 SGenProtocolPin *entry = data;
166                 return matches_interval (ptr, entry->obj, entry->size);
167         }
168         case SGEN_PROTOCOL_MARK: {
169                 SGenProtocolMark *entry = data;
170                 return matches_interval (ptr, entry->obj, entry->size);
171         }
172         case SGEN_PROTOCOL_WBARRIER: {
173                 SGenProtocolWBarrier *entry = data;
174                 return ptr == entry->ptr || ptr == entry->value;
175         }
176         case SGEN_PROTOCOL_GLOBAL_REMSET: {
177                 SGenProtocolGlobalRemset *entry = data;
178                 return ptr == entry->ptr || ptr == entry->value;
179         }
180         case SGEN_PROTOCOL_PTR_UPDATE: {
181                 SGenProtocolPtrUpdate *entry = data;
182                 return ptr == entry->ptr ||
183                         matches_interval (ptr, entry->old_value, entry->size) ||
184                         matches_interval (ptr, entry->new_value, entry->size);
185         }
186         case SGEN_PROTOCOL_CLEANUP: {
187                 SGenProtocolCleanup *entry = data;
188                 return matches_interval (ptr, entry->ptr, entry->size);
189         }
190         case SGEN_PROTOCOL_EMPTY: {
191                 SGenProtocolEmpty *entry = data;
192                 return matches_interval (ptr, entry->start, entry->size);
193         }
194         case SGEN_PROTOCOL_MISSING_REMSET: {
195                 SGenProtocolMissingRemset *entry = data;
196                 return ptr == entry->obj || ptr == entry->value || ptr == (char*)entry->obj + entry->offset;
197         }
198         default:
199                 assert (0);
200         }
201 }
202
203 int
204 main (int argc, char *argv[])
205 {
206         int type;
207         void *data;
208         int num_nums = argc - 1;
209         int i;
210         long nums [num_nums];
211
212         for (i = 0; i < num_nums; ++i)
213                 nums [i] = strtoul (argv [i + 1], NULL, 16);
214
215         while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
216                 gboolean match = FALSE;
217                 for (i = 0; i < num_nums; ++i) {
218                         if (is_match ((gpointer) nums [i], type, data)) {
219                                 match = TRUE;
220                                 break;
221                         }
222                 }
223                 if (match)
224                         print_entry (type, data);
225                 free (data);
226         }
227
228         return 0;
229 }