111
|
1 /* go-fieldtrack.c -- structure field data analysis.
|
|
2
|
|
3 Copyright 2012 The Go Authors. All rights reserved.
|
|
4 Use of this source code is governed by a BSD-style
|
|
5 license that can be found in the LICENSE file. */
|
|
6
|
|
7 #include "runtime.h"
|
|
8
|
|
9 /* The compiler will track fields that have the tag go:"track". Any
|
|
10 function that refers to such a field will call this function with a
|
|
11 string
|
|
12 fieldtrack "package.type.field"
|
|
13
|
|
14 This function does not actually do anything. Instead, we gather
|
|
15 the field tracking information by looking for strings of that form
|
|
16 in the read-only data section. This is, of course, a horrible
|
|
17 hack, but it's good enough for now. We can improve it, e.g., by a
|
|
18 linker plugin, if this turns out to be useful. */
|
|
19
|
|
20 void
|
|
21 __go_fieldtrack (byte *p __attribute__ ((unused)))
|
|
22 {
|
|
23 }
|
|
24
|
|
25 /* A runtime function to add all the tracked fields to a
|
|
26 map[string]bool. */
|
|
27
|
145
|
28 extern void *mapassign (const struct maptype *, void *hmap, const void *key)
|
111
|
29 __asm__ (GOSYM_PREFIX "runtime.mapassign");
|
|
30
|
|
31 // The type descriptor for map[string] bool. */
|
131
|
32 extern const char map_string_bool[] __attribute__ ((weak));
|
|
33 extern const char map_string_bool[]
|
|
34 __asm__ (GOSYM_PREFIX "type..map.6string.7bool");
|
111
|
35
|
|
36 void runtime_Fieldtrack (void *) __asm__ (GOSYM_PREFIX "runtime.Fieldtrack");
|
|
37
|
|
38 void
|
|
39 runtime_Fieldtrack (void *m)
|
|
40 {
|
|
41 const char *p;
|
|
42 const char *pend;
|
|
43 const char *prefix;
|
|
44 size_t prefix_len;
|
|
45
|
131
|
46 if (map_string_bool == NULL)
|
111
|
47 return;
|
|
48
|
|
49 p = __data_start;
|
|
50 if (p == NULL)
|
|
51 p = __etext;
|
|
52 if (p == NULL)
|
|
53 p = _etext;
|
|
54 if (p == NULL)
|
|
55 return;
|
|
56
|
|
57 pend = __edata;
|
|
58 if (pend == NULL)
|
|
59 pend = _edata;
|
|
60 if (pend == NULL)
|
|
61 pend = __bss_start;
|
|
62 if (pend == NULL)
|
|
63 return;
|
|
64
|
|
65 prefix = "fieldtrack ";
|
|
66 prefix_len = __builtin_strlen (prefix);
|
|
67
|
|
68 while (p < pend)
|
|
69 {
|
|
70 const char *q1;
|
|
71 const char *q2;
|
|
72
|
|
73 q1 = __builtin_memchr (p + prefix_len, '"', pend - (p + prefix_len));
|
|
74 if (q1 == NULL)
|
|
75 break;
|
|
76
|
|
77 if (__builtin_memcmp (q1 - prefix_len, prefix, prefix_len) != 0)
|
|
78 {
|
|
79 p = q1 + 1;
|
|
80 continue;
|
|
81 }
|
|
82
|
|
83 q1++;
|
|
84 q2 = __builtin_memchr (q1, '"', pend - q1);
|
|
85 if (q2 == NULL)
|
|
86 break;
|
|
87
|
|
88 if (__builtin_memchr (q1, '\0', q2 - q1) == NULL)
|
|
89 {
|
|
90 String s;
|
|
91 void *p;
|
|
92
|
|
93 s.str = (const byte *) q1;
|
|
94 s.len = q2 - q1;
|
131
|
95 p = mapassign((const void*) map_string_bool, m, &s);
|
111
|
96 *(_Bool*)p = 1;
|
|
97 }
|
|
98
|
|
99 p = q2;
|
|
100 }
|
|
101 }
|