2016-07-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
[official-gcc.git] / libgo / runtime / go-fieldtrack.c
bloba7e2c133440e17685ad4144802c93f4a8e35628d
1 /* go-fieldtrack.c -- structure field data analysis.
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. */
7 #include "runtime.h"
8 #include "go-type.h"
9 #include "map.h"
11 /* The compiler will track fields that have the tag go:"track". Any
12 function that refers to such a field will call this function with a
13 string
14 fieldtrack "package.type.field"
16 This function does not actually do anything. Instead, we gather
17 the field tracking information by looking for strings of that form
18 in the read-only data section. This is, of course, a horrible
19 hack, but it's good enough for now. We can improve it, e.g., by a
20 linker plugin, if this turns out to be useful. */
22 void
23 __go_fieldtrack (byte *p __attribute__ ((unused)))
27 /* A runtime function to add all the tracked fields to a
28 map[string]bool. */
30 extern const char _etext[] __attribute__ ((weak));
31 extern const char __etext[] __attribute__ ((weak));
32 extern const char __data_start[] __attribute__ ((weak));
33 extern const char _edata[] __attribute__ ((weak));
34 extern const char __edata[] __attribute__ ((weak));
35 extern const char __bss_start[] __attribute__ ((weak));
37 void runtime_Fieldtrack (struct __go_map *) __asm__ (GOSYM_PREFIX "runtime.Fieldtrack");
39 void
40 runtime_Fieldtrack (struct __go_map *m)
42 const char *p;
43 const char *pend;
44 const char *prefix;
45 size_t prefix_len;
47 p = __data_start;
48 if (p == NULL)
49 p = __etext;
50 if (p == NULL)
51 p = _etext;
52 if (p == NULL)
53 return;
55 pend = __edata;
56 if (pend == NULL)
57 pend = _edata;
58 if (pend == NULL)
59 pend = __bss_start;
60 if (pend == NULL)
61 return;
63 prefix = "fieldtrack ";
64 prefix_len = __builtin_strlen (prefix);
66 while (p < pend)
68 const char *q1;
69 const char *q2;
71 q1 = __builtin_memchr (p + prefix_len, '"', pend - (p + prefix_len));
72 if (q1 == NULL)
73 break;
75 if (__builtin_memcmp (q1 - prefix_len, prefix, prefix_len) != 0)
77 p = q1 + 1;
78 continue;
81 q1++;
82 q2 = __builtin_memchr (q1, '"', pend - q1);
83 if (q2 == NULL)
84 break;
86 if (__builtin_memchr (q1, '\0', q2 - q1) == NULL)
88 String s;
89 void *v;
90 _Bool *pb;
92 s.str = (const byte *) q1;
93 s.len = q2 - q1;
94 v = __go_map_index (m, &s, 1);
95 pb = (_Bool *) v;
96 *pb = 1;
99 p = q2;