tools/perf/util/machine.c

Source file repositories/reference/linux-study-clean/tools/perf/util/machine.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/machine.c
Extension
.c
Size
86355 bytes
Lines
3341
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 machine_fprintf_cb_args {
	FILE *fp;
	size_t printed;
};

static int machine_fprintf_cb(struct thread *thread, void *data)
{
	struct machine_fprintf_cb_args *args = data;

	/* TODO: handle fprintf errors. */
	args->printed += thread__fprintf(thread, args->fp);
	return 0;
}

size_t machine__fprintf(struct machine *machine, FILE *fp)
{
	struct machine_fprintf_cb_args args = {
		.fp = fp,
		.printed = 0,
	};
	size_t ret = fprintf(fp, "Threads: %zu\n", threads__nr(&machine->threads));

	machine__for_each_thread(machine, machine_fprintf_cb, &args);
	return ret + args.printed;
}

static struct dso *machine__get_kernel(struct machine *machine)
{
	const char *vmlinux_name = machine->mmap_name;
	struct dso *kernel;

	if (machine__is_host(machine)) {
		if (symbol_conf.vmlinux_name)
			vmlinux_name = symbol_conf.vmlinux_name;

		kernel = machine__findnew_kernel(machine, vmlinux_name,
						 "[kernel]", DSO_SPACE__KERNEL);
	} else {
		if (symbol_conf.default_guest_vmlinux_name)
			vmlinux_name = symbol_conf.default_guest_vmlinux_name;

		kernel = machine__findnew_kernel(machine, vmlinux_name,
						 "[guest.kernel]",
						 DSO_SPACE__KERNEL_GUEST);
	}

	if (kernel != NULL && (!dso__has_build_id(kernel)))
		dso__read_running_kernel_build_id(kernel, machine);

	return kernel;
}

void machine__get_kallsyms_filename(struct machine *machine, char *buf,
				    size_t bufsz)
{
	if (machine__is_default_guest(machine))
		scnprintf(buf, bufsz, "%s", symbol_conf.default_guest_kallsyms);
	else
		scnprintf(buf, bufsz, "%s/proc/kallsyms", machine->root_dir);
}

const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL};

/* Figure out the start address of kernel map from /proc/kallsyms.
 * Returns the name of the start symbol in *symbol_name. Pass in NULL as
 * symbol_name if it's not that important.
 */
static int machine__get_running_kernel_start(struct machine *machine,
					     const char **symbol_name,
					     u64 *start, u64 *end)
{
	char filename[PATH_MAX];
	int i, err = -1;
	const char *name;
	u64 addr = 0;

	machine__get_kallsyms_filename(machine, filename, PATH_MAX);

	if (symbol__restricted_filename(filename, "/proc/kallsyms"))
		return 0;

	for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) {
		err = kallsyms__get_function_start(filename, name, &addr);
		if (!err)
			break;
	}

	if (err)
		return -1;

Annotation

Implementation Notes