tools/perf/util/libbfd.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/util/libbfd.c
Extension
.c
Size
13920 bytes
Lines
646
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 a2l_data {
	const char *input;
	u64 addr;

	bool found;
	const char *filename;
	const char *funcname;
	unsigned int line;

	bfd *abfd;
	asymbol **syms;
};

static bool perf_bfd_lock(void *bfd_mutex)
{
	mutex_lock(bfd_mutex);
	return true;
}

static bool perf_bfd_unlock(void *bfd_mutex)
{
	mutex_unlock(bfd_mutex);
	return true;
}

static void perf_bfd_init(void)
{
	static struct mutex bfd_mutex;

	mutex_init_recursive(&bfd_mutex);

	if (bfd_init() != BFD_INIT_MAGIC) {
		pr_err("Error initializing libbfd\n");
		return;
	}
	if (!bfd_thread_init(perf_bfd_lock, perf_bfd_unlock, &bfd_mutex))
		pr_err("Error initializing libbfd threading\n");
}

static void ensure_bfd_init(void)
{
	static pthread_once_t bfd_init_once = PTHREAD_ONCE_INIT;

	pthread_once(&bfd_init_once, perf_bfd_init);
}

static int bfd_error(const char *string)
{
	const char *errmsg;

	errmsg = bfd_errmsg(bfd_get_error());
	fflush(stdout);

	if (string)
		pr_debug("%s: %s\n", string, errmsg);
	else
		pr_debug("%s\n", errmsg);

	return -1;
}

static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
{
	long storage;
	long symcount;
	asymbol **syms;
	bfd_boolean dynamic = FALSE;

	if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
		return bfd_error(bfd_get_filename(abfd));

	storage = bfd_get_symtab_upper_bound(abfd);
	if (storage == 0L) {
		storage = bfd_get_dynamic_symtab_upper_bound(abfd);
		dynamic = TRUE;
	}
	if (storage < 0L)
		return bfd_error(bfd_get_filename(abfd));

	syms = malloc(storage);
	if (dynamic)
		symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
	else
		symcount = bfd_canonicalize_symtab(abfd, syms);

	if (symcount < 0) {
		free(syms);
		return bfd_error(bfd_get_filename(abfd));
	}

Annotation

Implementation Notes