github.com/golang/gofrontend@v0.0.0-20240429183944-60f985a78526/libgo/runtime/go-fieldtrack.c (about) 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 28 extern void *mapassign (const struct maptype *, void *hmap, const void *key) 29 __asm__ (GOSYM_PREFIX "runtime.mapassign"); 30 31 // The type descriptor for map[string] bool. */ 32 extern const char map_string_bool[] __attribute__ ((weak)); 33 extern const char map_string_bool[] 34 __asm__ (GOSYM_PREFIX "type..map_6string_7bool"); 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 46 if (map_string_bool == NULL) 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; 95 p = mapassign((const void*) map_string_bool, m, &s); 96 *(_Bool*)p = 1; 97 } 98 99 p = q2; 100 } 101 }