// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
/*
* BTF-to-C type converter.
*
* Copyright (c) 2019 Facebook
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <linux/err.h>
#include <linux/btf.h>
#include "btf.h"
#include "hashmap.h"
#include "libbpf.h"
#include "libbpf_internal.h"
static const char PREFIXES[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
static const size_t PREFIX_CNT = sizeof(PREFIXES) - 1;
static const char *pfx(int lvl)
{
return lvl >= PREFIX_CNT ? PREFIXES : &PREFIXES[PREFIX_CNT - lvl];
}
enum btf_dump_type_order_state {
NOT_ORDERED,
ORDERING,
ORDERED,
};
enum btf_dump_type_emit_state {
NOT_EMITTED,
EMITTING,
EMITTED,
};
/* per-type auxiliary state */
struct btf_dump_type_aux_state {
/* topological sorting state */
enum btf_dump_type_order_state order_state: 2;
/* emitting state used to determine the need for forward declaration */
enum btf_dump_type_emit_state emit_state: 2;
/* whether forward declaration was already emitted */
__u8 fwd_emitted: 1;
/* whether unique non-duplicate name was already assigned */
__u8 name_resolved: 1;
};
struct btf_dump {
const struct btf *btf;
const struct btf_ext *btf_ext;
btf_dump_printf_fn_t printf_fn;
struct btf_dump_opts opts;
/* per-type auxiliary state */
struct btf_dump_type_aux_state *type_states;
/* per-type optional cached unique name, must be freed, if present */
const char **cached_names;
/* topo-sorted list of dependent type definitions */
__u32 *emit_queue;
int emit_queue_cap;
int emit_queue_cnt;
/*
* stack of type declarations (e.g., chain of modifiers, arrays,
* funcs, etc)
*/
__u32 *decl_stack;
int decl_stack_cap;
int decl_stack_cnt;
/* maps struct/union/enum name to a number of name occurrences */
struct hashmap *type_names;
/*
* maps typedef identifiers and enum value names to a number of such
* name occurrences
*/
struct hashmap *ident_names;
};
static size_t str_hash_fn(const void *key, void *ctx)
{
const char *s = key;
size_t h = 0;
while (*s) {
h = h * 31 + *s;
s++;
}
return h;
}
static bool str_equal_fn(const void *a, const void *b, void *ctx)
{
return strcmp(a, b) == 0;
}
static __u16 btf_kind_of(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info);
}
static __u16 btf_vlen_of(const struct btf_type *t)
{
return BTF_INFO_VLEN(t->info);
}