tools/objtool/klp-diff.c

Source file repositories/reference/linux-study-clean/tools/objtool/klp-diff.c

File Facts

System
Linux kernel
Corpus path
tools/objtool/klp-diff.c
Extension
.c
Size
56796 bytes
Lines
2214
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct elfs {
	struct elf *orig, *patched, *out;
	const char *modname;
};

struct export {
	struct hlist_node hash;
	char *mod, *sym;
};

bool debug, debug_correlate, debug_clone;
int indent;

static const char * const klp_diff_usage[] = {
	"objtool klp diff [<options>] <in1.o> <in2.o> <out.o>",
	NULL,
};

static const struct option klp_diff_options[] = {
	OPT_GROUP("Options:"),
	OPT_BOOLEAN('d', "debug", &debug, "enable all debug output"),
	OPT_BOOLEAN(0, "debug-correlate", &debug_correlate, "enable correlation debug output"),
	OPT_BOOLEAN(0, "debug-clone", &debug_clone, "enable cloning debug output"),
	OPT_END(),
};

static DEFINE_HASHTABLE(exports, 15);

static char *escape_str(const char *orig)
{
	size_t len = 0;
	const char *a;
	char *b, *new;

	for (a = orig; *a; a++) {
		switch (*a) {
		case '\001': len += 5; break;
		case '\n':
		case '\t':   len += 2; break;
		default: len++;
		}
	}

	new = malloc(len + 1);
	if (!new)
		return NULL;

	for (a = orig, b = new; *a; a++) {
		switch (*a) {
		case '\001': memcpy(b, "<SOH>", 5); b += 5; break;
		case '\n': *b++ = '\\'; *b++ = 'n'; break;
		case '\t': *b++ = '\\'; *b++ = 't'; break;
		default:   *b++ = *a;
		}
	}

	*b = '\0';
	return new;
}

static int read_exports(void)
{
	const char *symvers = "Module.symvers";
	char line[1024], *path = NULL;
	unsigned int line_num = 1;
	FILE *file;

	file = fopen(symvers, "r");
	if (!file) {
		path = top_level_dir(symvers);
		if (!path) {
			ERROR("can't open '%s', \"objtool diff\" should be run from the kernel tree", symvers);
			return -1;
		}

		file = fopen(path, "r");
		if (!file) {
			ERROR_GLIBC("fopen");
			return -1;
		}
	}

	while (fgets(line, 1024, file)) {
		char *sym, *mod, *type;
		struct export *export;

		sym = strchr(line, '\t');
		if (!sym) {
			ERROR("malformed Module.symvers (sym) at line %d", line_num);
			return -1;

Annotation

Implementation Notes