+// SPDX-License-Identifier: ISC
/*
* Copyright (c) 2017-20 David Lamparter, for NetDEF, Inc.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
struct xref_block *xref_blocks;
static struct xref_block **xref_block_last = &xref_blocks;
+struct xrefdata_uid_head xrefdata_uid = INIT_RBTREE_UNIQ(xrefdata_uid);
+
static void base32(uint8_t **inpos, int *bitpos,
char *out, size_t n_chars)
{
*bitpos = bp;
}
+static void xref_add_one(const struct xref *xref)
+{
+ SHA256_CTX sha;
+ struct xrefdata *xrefdata;
+
+ const char *filename, *p, *q;
+ uint8_t hash[32], *h = hash;
+ uint32_t be_val;
+ int bitpos;
+
+ if (!xref || !xref->xrefdata)
+ return;
+
+ xrefdata = xref->xrefdata;
+ xrefdata->xref = xref;
+
+ if (!xrefdata->hashstr)
+ return;
+
+ /* as far as the unique ID is concerned, only use the last
+ * directory name + filename, e.g. "bgpd/bgp_route.c". This
+ * gives a little leeway in moving things and avoids IDs being
+ * screwed up by out of tree builds or absolute pathnames.
+ */
+ filename = xref->file;
+ p = strrchr(filename, '/');
+ if (p) {
+ q = memrchr(filename, '/', p - filename);
+ if (q)
+ filename = q + 1;
+ }
+
+ SHA256_Init(&sha);
+ SHA256_Update(&sha, filename, strlen(filename));
+ SHA256_Update(&sha, xrefdata->hashstr,
+ strlen(xrefdata->hashstr));
+ be_val = htonl(xrefdata->hashu32[0]);
+ SHA256_Update(&sha, &be_val, sizeof(be_val));
+ be_val = htonl(xrefdata->hashu32[1]);
+ SHA256_Update(&sha, &be_val, sizeof(be_val));
+ SHA256_Final(hash, &sha);
+
+ bitpos = -1;
+ base32(&h, &bitpos, &xrefdata->uid[0], 5);
+ xrefdata->uid[5] = '-';
+ base32(&h, &bitpos, &xrefdata->uid[6], 5);
+
+ xrefdata_uid_add(&xrefdata_uid, xrefdata);
+}
+
+void xref_gcc_workaround(const struct xref *xref)
+{
+ xref_add_one(xref);
+}
+
void xref_block_add(struct xref_block *block)
{
const struct xref * const *xrefp;
- SHA256_CTX sha;
*xref_block_last = block;
xref_block_last = &block->next;
- for (xrefp = block->start; xrefp < block->stop; xrefp++) {
- const struct xref *xref = *xrefp;
- struct xrefdata *xrefdata;
-
- const char *filename, *p, *q;
- uint8_t hash[32], *h = hash;
- uint32_t be_val;
- int bitpos;
-
- if (!xref || !xref->xrefdata)
- continue;
-
- xrefdata = xref->xrefdata;
- xrefdata->xref = xref;
-
- if (!xrefdata->hashstr)
- continue;
-
- /* as far as the unique ID is concerned, only use the last
- * directory name + filename, e.g. "bgpd/bgp_route.c". This
- * gives a little leeway in moving things and avoids IDs being
- * screwed up by out of tree builds or absolute pathnames.
- */
- filename = xref->file;
- p = strrchr(filename, '/');
- if (p) {
- q = memrchr(filename, '/', p - filename);
- if (q)
- filename = q + 1;
- else
- filename = p + 1;
- }
-
- SHA256_Init(&sha);
- SHA256_Update(&sha, filename, strlen(filename));
- SHA256_Update(&sha, xrefdata->hashstr,
- strlen(xrefdata->hashstr));
- be_val = htonl(xrefdata->hashu32[0]);
- SHA256_Update(&sha, &be_val, sizeof(be_val));
- be_val = htonl(xrefdata->hashu32[1]);
- SHA256_Update(&sha, &be_val, sizeof(be_val));
- SHA256_Final(hash, &sha);
-
- bitpos = -1;
- base32(&h, &bitpos, &xrefdata->uid[0], 5);
- xrefdata->uid[5] = '-';
- base32(&h, &bitpos, &xrefdata->uid[6], 5);
- }
+ for (xrefp = block->start; xrefp < block->stop; xrefp++)
+ xref_add_one(*xrefp);
}