__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2024 Google LLC
 */

#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>

#include "gendwarfksyms.h"

#define KABI_RULE_SECTION ".discard.gendwarfksyms.kabi_rules"
#define KABI_RULE_VERSION "1"

/*
 * The rule section consists of four null-terminated strings per
 * entry:
 *
 *   1. version
 *      Entry format version. Must match KABI_RULE_VERSION.
 *
 *   2. type
 *      Type of the kABI rule. Must be one of the tags defined below.
 *
 *   3. target
 *      Rule-dependent target, typically the fully qualified name of
 *      the target DIE.
 *
 *   4. value
 *      Rule-dependent value.
 */
#define KABI_RULE_MIN_ENTRY_SIZE                                  \
	(/* version\0 */ 2 + /* type\0 */ 2 + /* target\0" */ 1 + \
	 /* value\0 */ 1)
#define KABI_RULE_EMPTY_VALUE ""

/*
 * Rule: declonly
 * - For the struct/enum/union in the target field, treat it as a
 *   declaration only even if a definition is available.
 */
#define KABI_RULE_TAG_DECLONLY "declonly"

/*
 * Rule: enumerator_ignore
 * - For the enum_field in the target field, ignore the enumerator.
 */
#define KABI_RULE_TAG_ENUMERATOR_IGNORE "enumerator_ignore"

/*
 * Rule: enumerator_value
 * - For the fqn_field in the target field, set the value to the
 *   unsigned integer in the value field.
 */
#define KABI_RULE_TAG_ENUMERATOR_VALUE "enumerator_value"

enum kabi_rule_type {
	KABI_RULE_TYPE_UNKNOWN,
	KABI_RULE_TYPE_DECLONLY,
	KABI_RULE_TYPE_ENUMERATOR_IGNORE,
	KABI_RULE_TYPE_ENUMERATOR_VALUE,
};

#define RULE_HASH_BITS 7

struct rule {
	enum kabi_rule_type type;
	const char *target;
	const char *value;
	struct hlist_node hash;
};

/* { type, target } -> struct rule */
static HASHTABLE_DEFINE(rules, 1 << RULE_HASH_BITS);

static inline unsigned int rule_values_hash(enum kabi_rule_type type,
					    const char *target)
{
	return hash_32(type) ^ hash_str(target);
}

static inline unsigned int rule_hash(const struct rule *rule)
{
	return rule_values_hash(rule->type, rule->target);
}

static inline const char *get_rule_field(const char **pos, ssize_t *left)
{
	const char *start = *pos;
	size_t len;

	if (*left <= 0)
		error("unexpected end of kABI rules");

	len = strnlen(start, *left) + 1;
	*pos += len;
	*left -= len;

	return start;
}

void kabi_read_rules(int fd)
{
	GElf_Shdr shdr_mem;
	GElf_Shdr *shdr;
	Elf_Data *rule_data = NULL;
	Elf_Scn *scn;
	Elf *elf;
	size_t shstrndx;
	const char *rule_str;
	ssize_t left;
	int i;

	const struct {
		enum kabi_rule_type type;
		const char *tag;
	} rule_types[] = {
		{
			.type = KABI_RULE_TYPE_DECLONLY,
			.tag = KABI_RULE_TAG_DECLONLY,
		},
		{
			.type = KABI_RULE_TYPE_ENUMERATOR_IGNORE,
			.tag = KABI_RULE_TAG_ENUMERATOR_IGNORE,
		},
		{
			.type = KABI_RULE_TYPE_ENUMERATOR_VALUE,
			.tag = KABI_RULE_TAG_ENUMERATOR_VALUE,
		},
	};

	if (!stable)
		return;

	if (elf_version(EV_CURRENT) != EV_CURRENT)
		error("elf_version failed: %s", elf_errmsg(-1));

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	if (!elf)
		error("elf_begin failed: %s", elf_errmsg(-1));

	if (elf_getshdrstrndx(elf, &shstrndx) < 0)
		error("elf_getshdrstrndx failed: %s", elf_errmsg(-1));

	scn = elf_nextscn(elf, NULL);

	while (scn) {
		const char *sname;

		shdr = gelf_getshdr(scn, &shdr_mem);
		if (!shdr)
			error("gelf_getshdr failed: %s", elf_errmsg(-1));

		sname = elf_strptr(elf, shstrndx, shdr->sh_name);
		if (!sname)
			error("elf_strptr failed: %s", elf_errmsg(-1));

		if (!strcmp(sname, KABI_RULE_SECTION)) {
			rule_data = elf_getdata(scn, NULL);
			if (!rule_data)
				error("elf_getdata failed: %s", elf_errmsg(-1));
			break;
		}

		scn = elf_nextscn(elf, scn);
	}

	if (!rule_data) {
		debug("kABI rules not found");
		check(elf_end(elf));
		return;
	}

	rule_str = rule_data->d_buf;
	left = shdr->sh_size;

	if (left < KABI_RULE_MIN_ENTRY_SIZE)
		error("kABI rule section too small: %zd bytes", left);

	if (rule_str[left - 1] != '\0')
		error("kABI rules are not null-terminated");

	while (left > KABI_RULE_MIN_ENTRY_SIZE) {
		enum kabi_rule_type type = KABI_RULE_TYPE_UNKNOWN;
		const char *field;
		struct rule *rule;

		/* version */
		field = get_rule_field(&rule_str, &left);

		if (strcmp(field, KABI_RULE_VERSION))
			error("unsupported kABI rule version: '%s'", field);

		/* type */
		field = get_rule_field(&rule_str, &left);

		for (i = 0; i < ARRAY_SIZE(rule_types); i++) {
			if (!strcmp(field, rule_types[i].tag)) {
				type = rule_types[i].type;
				break;
			}
		}

		if (type == KABI_RULE_TYPE_UNKNOWN)
			error("unsupported kABI rule type: '%s'", field);

		rule = xmalloc(sizeof(struct rule));

		rule->type = type;
		rule->target = xstrdup(get_rule_field(&rule_str, &left));
		rule->value = xstrdup(get_rule_field(&rule_str, &left));

		hash_add(rules, &rule->hash, rule_hash(rule));

		debug("kABI rule: type: '%s', target: '%s', value: '%s'", field,
		      rule->target, rule->value);
	}

	if (left > 0)
		warn("unexpected data at the end of the kABI rules section");

	check(elf_end(elf));
}

bool kabi_is_declonly(const char *fqn)
{
	struct rule *rule;

	if (!stable)
		return false;
	if (!fqn || !*fqn)
		return false;

	hash_for_each_possible(rules, rule, hash,
			       rule_values_hash(KABI_RULE_TYPE_DECLONLY, fqn)) {
		if (rule->type == KABI_RULE_TYPE_DECLONLY &&
		    !strcmp(fqn, rule->target))
			return true;
	}

	return false;
}

static char *get_enumerator_target(const char *fqn, const char *field)
{
	char *target = NULL;

	if (asprintf(&target, "%s %s", fqn, field) < 0)
		error("asprintf failed for '%s %s'", fqn, field);

	return target;
}

static unsigned long get_ulong_value(const char *value)
{
	unsigned long result = 0;
	char *endptr = NULL;

	errno = 0;
	result = strtoul(value, &endptr, 10);

	if (errno || *endptr)
		error("invalid unsigned value '%s'", value);

	return result;
}

bool kabi_is_enumerator_ignored(const char *fqn, const char *field)
{
	bool match = false;
	struct rule *rule;
	char *target;

	if (!stable)
		return false;
	if (!fqn || !*fqn || !field || !*field)
		return false;

	target = get_enumerator_target(fqn, field);

	hash_for_each_possible(
		rules, rule, hash,
		rule_values_hash(KABI_RULE_TYPE_ENUMERATOR_IGNORE, target)) {
		if (rule->type == KABI_RULE_TYPE_ENUMERATOR_IGNORE &&
		    !strcmp(target, rule->target)) {
			match = true;
			break;
		}
	}

	free(target);
	return match;
}

bool kabi_get_enumerator_value(const char *fqn, const char *field,
			       unsigned long *value)
{
	bool match = false;
	struct rule *rule;
	char *target;

	if (!stable)
		return false;
	if (!fqn || !*fqn || !field || !*field)
		return false;

	target = get_enumerator_target(fqn, field);

	hash_for_each_possible(rules, rule, hash,
			       rule_values_hash(KABI_RULE_TYPE_ENUMERATOR_VALUE,
						target)) {
		if (rule->type == KABI_RULE_TYPE_ENUMERATOR_VALUE &&
		    !strcmp(target, rule->target)) {
			*value = get_ulong_value(rule->value);
			match = true;
			break;
		}
	}

	free(target);
	return match;
}

void kabi_free(void)
{
	struct hlist_node *tmp;
	struct rule *rule;

	hash_for_each_safe(rules, rule, tmp, hash) {
		free((void *)rule->target);
		free((void *)rule->value);
		free(rule);
	}

	hash_init(rules);
}

Filemanager

Name Type Size Permission Actions
examples Folder 0755
Makefile File 333 B 0644
cache.c File 869 B 0644
cache.o File 2.12 KB 0644
die.c File 3.06 KB 0644
die.o File 5.45 KB 0644
dwarf.c File 28.57 KB 0644
dwarf.o File 38.48 KB 0644
gendwarfksyms File 64.47 KB 0755
gendwarfksyms.c File 4.06 KB 0644
gendwarfksyms.h File 7.06 KB 0644
gendwarfksyms.o File 9.23 KB 0644
kabi.c File 7.04 KB 0644
kabi.o File 10.2 KB 0644
symbols.c File 7.63 KB 0644
symbols.o File 12.09 KB 0644
types.c File 10.43 KB 0644
types.o File 14.15 KB 0644
Filemanager