1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2017-20 David Lamparter, for NetDEF, Inc.
24 struct xref_block
*xref_blocks
;
25 static struct xref_block
**xref_block_last
= &xref_blocks
;
27 struct xrefdata_uid_head xrefdata_uid
= INIT_RBTREE_UNIQ(xrefdata_uid
);
29 static void base32(uint8_t **inpos
, int *bitpos
,
30 char *out
, size_t n_chars
)
32 static const char base32ch
[] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
38 while (opos
< out
+ n_chars
) {
39 uint32_t bits
= in
[0] | (in
[1] << 8);
46 *opos
++ = base32ch
[bits
& 0x1f];
57 static void xref_add_one(const struct xref
*xref
)
60 struct xrefdata
*xrefdata
;
62 const char *filename
, *p
, *q
;
63 uint8_t hash
[32], *h
= hash
;
67 if (!xref
|| !xref
->xrefdata
)
70 xrefdata
= xref
->xrefdata
;
71 xrefdata
->xref
= xref
;
73 if (!xrefdata
->hashstr
)
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.
81 filename
= xref
->file
;
82 p
= strrchr(filename
, '/');
84 q
= memrchr(filename
, '/', p
- filename
);
90 SHA256_Update(&sha
, filename
, strlen(filename
));
91 SHA256_Update(&sha
, xrefdata
->hashstr
,
92 strlen(xrefdata
->hashstr
));
93 be_val
= htonl(xrefdata
->hashu32
[0]);
94 SHA256_Update(&sha
, &be_val
, sizeof(be_val
));
95 be_val
= htonl(xrefdata
->hashu32
[1]);
96 SHA256_Update(&sha
, &be_val
, sizeof(be_val
));
97 SHA256_Final(hash
, &sha
);
100 base32(&h
, &bitpos
, &xrefdata
->uid
[0], 5);
101 xrefdata
->uid
[5] = '-';
102 base32(&h
, &bitpos
, &xrefdata
->uid
[6], 5);
104 xrefdata_uid_add(&xrefdata_uid
, xrefdata
);
107 void xref_gcc_workaround(const struct xref
*xref
)
112 void xref_block_add(struct xref_block
*block
)
114 const struct xref
* const *xrefp
;
116 *xref_block_last
= block
;
117 xref_block_last
= &block
->next
;
119 for (xrefp
= block
->start
; xrefp
< block
->stop
; xrefp
++)
120 xref_add_one(*xrefp
);