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  }