Linux-Trace-Devel Archive on lore.kernel.org
 help / color / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com>
Cc: linux-trace-devel@vger.kernel.org
Subject: Re: [PATCH v2 2/3] trace-cmd: New internal APIs for reading ELF header
Date: Thu, 17 Sep 2020 09:42:35 -0400
Message-ID: <20200917094235.05098d69@gandalf.local.home> (raw)
In-Reply-To: <20200916114709.291533-3-tz.stoyanov@gmail.com>

On Wed, 16 Sep 2020 14:47:08 +0300
"Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com> wrote:

> +#define RESOLVE_NAME		(1 << 0)
> +#define RESOLVE_VMA		(1 << 1)
> +#define RESOLVE_FOFFSET		(1 << 2)
> +struct trace_obj_job {
> +	unsigned int flags;
> +	unsigned long long addr_offset;
> +	struct debug_symbols *symbols;
> +};
> +
> +struct dwarf_bfd_context {
> +	asymbol **table;
> +	struct trace_obj_job *job;
> +};
> +
> +static void bfd_dwarf_section(bfd *abfd, asection *section, void *param)

Another small comment. Do not name any function that starts with "bfd_" as
that makes it hard to know the difference between these functions and
functions from the bfd library. The only functions that should have bfd_ as
the start are those in the library.

Could call this: dwarf_bfd_section()?


> +{
> +	struct dwarf_bfd_context *context = (struct dwarf_bfd_context *)param;
> +	unsigned int discriminator;
> +	const char *functionname;
> +	struct debug_symbols *s;
> +	unsigned long long vma;
> +	const char *filename;
> +	unsigned int line;
> +	bfd_boolean found;
> +
> +	if (!(section->flags & SEC_CODE))
> +		return;
> +
> +	for (s = context->job->symbols; s; s = s->next) {
> +		if (s->symbol.vma_near)
> +			vma = s->symbol.vma_near;
> +		else if (s->symbol.vma_start)
> +			vma = s->symbol.vma_start;
> +		else
> +			continue;
> +
> +		if (abfd->flags & DYNAMIC)
> +			vma -=  context->job->addr_offset;
> +		if (vma && section->vma <= vma &&
> +		    (section->vma + section->size) > vma) {
> +			if (!s->symbol.fname)
> +				s->symbol.fname = strdup(abfd->filename);
> +			if (context->job->flags & RESOLVE_FOFFSET)
> +				s->symbol.foffset = section->filepos + (vma - section->vma);
> +			if (!s->symbol.name && (context->job->flags & RESOLVE_NAME)) {
> +				found = bfd_find_nearest_line_discriminator(abfd, section, context->table,
> +									    vma - section->vma, &filename,
> +									    &functionname, &line, &discriminator);
> +				if (found)
> +					s->symbol.name = strdup(functionname);
> +			}
> +		}
> +	}
> +}
> +
> +static asymbol **get_sym_table(bfd *handle)
> +{
> +	bfd_boolean dyn = FALSE;
> +	asymbol **symtable;
> +	long count;
> +	long size;
> +
> +	if ((bfd_get_file_flags(handle) & HAS_SYMS) == 0)
> +		return NULL;
> +	size = bfd_get_symtab_upper_bound(handle);
> +	if (size == 0) {
> +		size = bfd_get_dynamic_symtab_upper_bound(handle);
> +		dyn = TRUE;
> +	}
> +	if (size <= 0)
> +		return NULL;
> +
> +	symtable = (asymbol **) calloc(1, size);
> +	if (!symtable)
> +		return NULL;
> +	if (dyn)
> +		count = bfd_canonicalize_dynamic_symtab(handle, symtable);
> +	else
> +		count = bfd_canonicalize_symtab(handle, symtable);
> +	if (count <= 0) {
> +		free(symtable);
> +		return NULL;
> +	}
> +/*
> + *	 alloc = bfd_demangle(cur_bfd, name, demangle_flags);
> + */
> +
> +	return symtable;
> +}
> +
> +static int sym_match(char *pattern, regex_t *regex, const char *symbol)
> +{
> +	if (strlen(pattern) == strlen(symbol) &&
> +	    !strcmp(pattern, symbol))
> +		return 0;
> +	if (regex && !regexec(regex, symbol, 0, NULL, 0))
> +		return 1;
> +
> +	return -1;
> +}
> +
> +static int bfd_symlookup(struct dwarf_bfd_context *context)

Same here: lookup_bfd_sym()?

> +{
> +	struct debug_symbols *s, *last = NULL;
> +	struct debug_symbols *new, *new_list = NULL;
> +	unsigned long long vma;
> +	asymbol **sp;
> +	int res = 0;
> +	int ret;
> +
> +	for (sp = context->table; *sp != NULL; sp++) {
> +		if (!((*sp)->flags & BSF_FUNCTION))
> +			continue;
> +		for (s = context->job->symbols; s; s = s->next) {
> +			last = s;
> +			ret = sym_match(s->symbol.name, s->regex, (*sp)->name);
> +			if (ret < 0)
> +				continue;
> +			vma = (*sp)->value + (*sp)->section->vma;
> +			if ((*sp)->the_bfd->flags & DYNAMIC)
> +				vma += context->job->addr_offset;
> +			if (ret == 0) { /* exact match */
> +				s->symbol.vma_start = vma;
> +			} else { /* regex pattern match */
> +				new = calloc(1, sizeof(struct debug_symbols));
> +				if (!new)
> +					break;
> +				new->symbol.name = strdup((*sp)->name);
> +				new->symbol.vma_start = vma;
> +				new->symbol.vma_near = s->symbol.vma_near;
> +				new->symbol.foffset = s->symbol.foffset;
> +				if (s->symbol.fname)
> +					new->symbol.fname = strdup(s->symbol.fname);
> +				new->next = new_list;
> +				new_list = new;
> +			}
> +			res++;
> +		}
> +	}
> +	if (last && !last->next)
> +		last->next = new_list;
> +
> +	return res;
> +}
> +
> +static int bfd_process_object(bfd *abfd, struct trace_obj_job *job)

find_bfd_process_object()?

> +{
> +	struct dwarf_bfd_context context;
> +	int ret = 0;
> +
> +	memset(&context, 0, sizeof(context));
> +	context.job = job;
> +
> +	if (bfd_check_format_matches(abfd, bfd_object, NULL) ||
> +	    bfd_check_format_matches(abfd, bfd_core, NULL)) {
> +		context.table = get_sym_table(abfd);
> +		if (job->flags & RESOLVE_VMA)
> +			bfd_symlookup(&context);
> +		if ((job->flags & RESOLVE_NAME) || (job->flags & RESOLVE_FOFFSET))
> +			bfd_map_over_sections(abfd, bfd_dwarf_section, &context);
> +		free(context.table);
> +	} else {
> +		ret = -1;
> +	}
> +
> +	return ret;
> +}
> +
> +static int bfd_read_all(bfd *abfd, struct trace_obj_job *job)

  read_all_bfd()?

-- Steve

> +{
> +	bfd *last_arfile = NULL;
> +	bfd *arfile = NULL;
> +	int ret = 0;
> +
> +	if (bfd_check_format(abfd, bfd_archive)) {
> +		for (;;) {
> +			bfd_set_error(bfd_error_no_error);
> +			arfile = bfd_openr_next_archived_file(abfd, arfile);
> +			if (!arfile) {
> +				if (bfd_get_error() != bfd_error_no_more_archived_files)
> +					break;
> +			}
> +			ret = bfd_read_all(arfile, job);
> +			if (last_arfile)
> +				bfd_close(last_arfile);
> +			last_arfile = arfile;
> +		}
> +		if (last_arfile)
> +			bfd_close(last_arfile);
> +	} else
> +		ret = bfd_process_object(abfd, job);
> +
> +	return ret;
> +}
> +

  reply index

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-16 11:47 [PATCH v2 0/3] Initial trace-cmd support for ftrace uprobes Tzvetomir Stoyanov (VMware)
2020-09-16 11:47 ` [PATCH v2 1/3] trace-cmd: Internal refactoring of pid address map logic Tzvetomir Stoyanov (VMware)
2020-09-16 11:47 ` [PATCH v2 2/3] trace-cmd: New internal APIs for reading ELF header Tzvetomir Stoyanov (VMware)
2020-09-17 13:42   ` Steven Rostedt [this message]
2020-09-16 11:47 ` [PATCH v2 3/3] trace-cmd: [POC] Add support for uprobes Tzvetomir Stoyanov (VMware)
2020-09-16 13:26 ` [PATCH v2 0/3] Initial trace-cmd support for ftrace uprobes Steven Rostedt
2020-09-17  1:07 ` Steven Rostedt
2020-09-24  7:14 Tzvetomir Stoyanov (VMware)
2020-09-24  7:14 ` [PATCH v2 2/3] trace-cmd: New internal APIs for reading ELF header Tzvetomir Stoyanov (VMware)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200917094235.05098d69@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=tz.stoyanov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Trace-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-trace-devel/0 linux-trace-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-trace-devel linux-trace-devel/ https://lore.kernel.org/linux-trace-devel \
		linux-trace-devel@vger.kernel.org
	public-inbox-index linux-trace-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-trace-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git