Coverage Report

Created: 2025-07-14 06:48

/src/frr/lib/xref.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: ISC
2
/*
3
 * Copyright (c) 2017-20  David Lamparter, for NetDEF, Inc.
4
 */
5
6
#ifdef HAVE_CONFIG_H
7
#include "config.h"
8
#endif
9
10
#include <stdlib.h>
11
#include <stdarg.h>
12
#include <string.h>
13
#include <pthread.h>
14
#include <signal.h>
15
#include <inttypes.h>
16
17
#include "xref.h"
18
#include "vty.h"
19
#include "jhash.h"
20
#include "sha256.h"
21
#include "memory.h"
22
#include "hash.h"
23
24
struct xref_block *xref_blocks;
25
static struct xref_block **xref_block_last = &xref_blocks;
26
27
struct xrefdata_uid_head xrefdata_uid = INIT_RBTREE_UNIQ(xrefdata_uid);
28
29
static void base32(uint8_t **inpos, int *bitpos,
30
       char *out, size_t n_chars)
31
0
{
32
0
  static const char base32ch[] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
33
34
0
  char *opos = out;
35
0
  uint8_t *in = *inpos;
36
0
  int bp = *bitpos;
37
38
0
  while (opos < out + n_chars) {
39
0
    uint32_t bits = in[0] | (in[1] << 8);
40
41
0
    if (bp == -1)
42
0
      bits |= 0x10;
43
0
    else
44
0
      bits >>= bp;
45
46
0
    *opos++ = base32ch[bits & 0x1f];
47
48
0
    bp += 5;
49
0
    if (bp >= 8)
50
0
      in++, bp -= 8;
51
0
  }
52
0
  *opos = '\0';
53
0
  *inpos = in;
54
0
  *bitpos = bp;
55
0
}
56
57
static void xref_add_one(const struct xref *xref)
58
41.7k
{
59
41.7k
  SHA256_CTX sha;
60
41.7k
  struct xrefdata *xrefdata;
61
62
41.7k
  const char *filename, *p, *q;
63
41.7k
  uint8_t hash[32], *h = hash;
64
41.7k
  uint32_t be_val;
65
41.7k
  int bitpos;
66
67
41.7k
  if (!xref || !xref->xrefdata)
68
41.7k
    return;
69
70
0
  xrefdata = xref->xrefdata;
71
0
  xrefdata->xref = xref;
72
73
0
  if (!xrefdata->hashstr)
74
0
    return;
75
76
  /* as far as the unique ID is concerned, only use the last
77
   * directory name + filename, e.g. "bgpd/bgp_route.c".  This
78
   * gives a little leeway in moving things and avoids IDs being
79
   * screwed up by out of tree builds or absolute pathnames.
80
   */
81
0
  filename = xref->file;
82
0
  p = strrchr(filename, '/');
83
0
  if (p) {
84
0
    q = memrchr(filename, '/', p - filename);
85
0
    if (q)
86
0
      filename = q + 1;
87
0
  }
88
89
0
  SHA256_Init(&sha);
90
0
  SHA256_Update(&sha, filename, strlen(filename));
91
0
  SHA256_Update(&sha, xrefdata->hashstr,
92
0
          strlen(xrefdata->hashstr));
93
0
  be_val = htonl(xrefdata->hashu32[0]);
94
0
  SHA256_Update(&sha, &be_val, sizeof(be_val));
95
0
  be_val = htonl(xrefdata->hashu32[1]);
96
0
  SHA256_Update(&sha, &be_val, sizeof(be_val));
97
0
  SHA256_Final(hash, &sha);
98
99
0
  bitpos = -1;
100
0
  base32(&h, &bitpos, &xrefdata->uid[0], 5);
101
0
  xrefdata->uid[5] = '-';
102
0
  base32(&h, &bitpos, &xrefdata->uid[6], 5);
103
104
0
  xrefdata_uid_add(&xrefdata_uid, xrefdata);
105
0
}
106
107
void xref_gcc_workaround(const struct xref *xref)
108
0
{
109
0
  xref_add_one(xref);
110
0
}
111
112
void xref_block_add(struct xref_block *block)
113
14
{
114
14
  const struct xref * const *xrefp;
115
116
14
  *xref_block_last = block;
117
14
  xref_block_last = &block->next;
118
119
41.7k
  for (xrefp = block->start; xrefp < block->stop; xrefp++)
120
41.7k
    xref_add_one(*xrefp);
121
14
}