From: Jiri Olsa <jolsa@redhat.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Veronika Kabatova <vkabatov@redhat.com>,
Andrii Nakryiko <andriin@fb.com>,
Alexei Starovoitov <ast@kernel.org>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
bpf <bpf@vger.kernel.org>, "Frank Ch. Eigler" <fche@redhat.com>,
Mark Wielaard <mjw@redhat.com>
Subject: Re: Build failures: unresolved symbol vfs_getattr
Date: Fri, 23 Oct 2020 22:17:02 +0200 [thread overview]
Message-ID: <20201023201702.GA2495983@krava> (raw)
In-Reply-To: <CAEf4BzbM=FhKUUjaM9msL1k=t_CSrhoWUNYcubzToZvbAJCJ-A@mail.gmail.com>
On Fri, Oct 23, 2020 at 11:22:05AM -0700, Andrii Nakryiko wrote:
> On Thu, Oct 22, 2020 at 11:58 PM Jiri Olsa <jolsa@redhat.com> wrote:
> >
> > On Fri, Oct 23, 2020 at 07:36:57AM +0200, Jiri Olsa wrote:
> > > On Thu, Oct 22, 2020 at 01:00:19PM -0700, Andrii Nakryiko wrote:
> > >
> > > SNIP
> > >
> > > > >
> > > > > hi,
> > > > > FYI there's still no solution yet, so far the progress is:
> > > > >
> > > > > the proposed workaround was to use the negation -> we don't have
> > > > > DW_AT_declaration tag, so let's find out instead which DW_TAG_subprogram
> > > > > tags have attached code and skip them if they don't have any:
> > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060#c10
> > > > >
> > > > > the attached patch is doing that, but the resulting BTF is missing
> > > > > several functions due to another bug in dwarf:
> > > > > https://bugzilla.redhat.com/show_bug.cgi?id=1890107
> > > >
> > > > It seems fine if there are only few functions (especially if those are
> > > > unlikely to be traced). Do you have an estimate of how many functions
> > > > have this second DWARF bug?
> > >
> > > it wasn't that many, I'll recheck
> >
> > 127 functions missing if the workaround is applied, list attached
> >
>
> some of those seem pretty useful... I guess the quick workaround in
> pahole would be to just remember function names that were emitted
> already. The problem with that is that we can pick a version without
> parameter names, which is not the end of the world, but certainly
> annoying.
right, we can generate them in bpftrace, but it's a shame
>
> But otherwise, I don't really have a good feeling what's the perfect
> solution here...
I tried the check of dwarf record against function symbols
with adresses mentioned earlier (attached)
getting more functions of course ;-)
$ bpftool btf dump file ./vmlinux | grep 'FUNC ' | wc -l
46606
compared to 22869 on the same .config with working gcc
and current pahole
and resolve_btfids is happy, because there are no duplications
jirka
---
diff --git a/btf_encoder.c b/btf_encoder.c
index 2a6455be4c52..468781204cd9 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -326,6 +326,18 @@ static int find_all_percpu_vars(struct btf_elf *btfe)
return 0;
}
+static bool btfe__generate_func(const struct btf_elf *btfe, const char *name)
+{
+ struct symbol *sym;
+
+ sym = btfe__find_symbol(btfe, name);
+ if (!sym || sym->generated || !sym->addr)
+ return false;
+
+ sym->generated = true;
+ return true;
+}
+
int cu__encode_btf(struct cu *cu, int verbose, bool force,
bool skip_encoding_vars)
{
@@ -354,6 +366,9 @@ int cu__encode_btf(struct cu *cu, int verbose, bool force,
if (!skip_encoding_vars && find_all_percpu_vars(btfe))
goto out;
+ if (btfe__load_symbols(btfe, cu))
+ goto out;
+
has_index_type = false;
need_index_type = false;
array_index_id = 0;
@@ -401,7 +416,7 @@ int cu__encode_btf(struct cu *cu, int verbose, bool force,
int btf_fnproto_id, btf_fn_id;
const char *name;
- if (fn->declaration || !fn->external)
+ if (!btfe__generate_func(btfe, function__name(fn, cu)))
continue;
btf_fnproto_id = btf_elf__add_func_proto(btfe, cu, &fn->proto, type_id_off);
diff --git a/elf_symtab.h b/elf_symtab.h
index 359add69c8ab..094ec4683d01 100644
--- a/elf_symtab.h
+++ b/elf_symtab.h
@@ -63,6 +63,14 @@ static inline uint64_t elf_sym__value(const GElf_Sym *sym)
return sym->st_value;
}
+static inline int elf_sym__is_function(const GElf_Sym *sym)
+{
+ return (elf_sym__type(sym) == STT_FUNC ||
+ elf_sym__type(sym) == STT_GNU_IFUNC) &&
+ sym->st_name != 0 &&
+ sym->st_shndx != SHN_UNDEF;
+}
+
static inline bool elf_sym__is_local_function(const GElf_Sym *sym)
{
return elf_sym__type(sym) == STT_FUNC &&
diff --git a/libbtf.c b/libbtf.c
index babf4fe8cd9e..6c4b8a069b85 100644
--- a/libbtf.c
+++ b/libbtf.c
@@ -30,6 +30,91 @@
uint8_t btf_elf__verbose;
uint8_t btf_elf__force;
+static int btfe__insert_symbol(struct btf_elf *btfe, const char *name,
+ uint64_t addr)
+{
+ struct rb_node **p = &btfe->symbols.rb_node;
+ struct rb_node *parent = NULL;
+ struct symbol *sym;
+ int err;
+
+ while (*p != NULL) {
+ parent = *p;
+ sym = rb_entry(parent, struct symbol, rb_node);
+
+
+ err = strcmp(sym->name, name);
+ if (err < 0)
+ p = &(*p)->rb_left;
+ else if (err > 0)
+ p = &(*p)->rb_right;
+ else
+ return 0;
+ }
+
+ sym = malloc(sizeof(*sym));
+ if (!sym)
+ return -1;
+ sym->name = name;
+ sym->addr = addr;
+ sym->generated = false;
+
+ rb_link_node(&sym->rb_node, parent, p);
+ rb_insert_color(&sym->rb_node, &btfe->symbols);
+ return 0;
+}
+
+struct symbol *btfe__find_symbol(const struct btf_elf *btfe, const char *name)
+{
+ struct symbol *sym;
+ struct rb_node *n;
+ int err;
+
+ n = btfe->symbols.rb_node;
+
+ while (n) {
+ sym = rb_entry(n, struct symbol, rb_node);
+ err = strcmp(sym->name, name);
+ if (err < 0)
+ n = n->rb_left;
+ else if (err > 0)
+ n = n->rb_right;
+ else
+ return sym;
+ }
+
+ return NULL;
+}
+
+int btfe__load_symbols(struct btf_elf *btfe, struct cu *cu)
+{
+ const char *name;
+ GElf_Sym sym;
+ uint32_t id;
+
+ cu__cache_symtab(cu);
+
+ cu__for_each_cached_symtab_entry(cu, id, sym, name) {
+ if (!elf_sym__is_function(&sym))
+ continue;
+ if (btfe__insert_symbol(btfe, name, elf_sym__value(&sym)))
+ return -1;
+ }
+ return 0;
+}
+
+static void btfe__delete_symbols(struct btf_elf *btfe)
+{
+ struct rb_node *n = rb_first(&btfe->symbols);
+ struct symbol *sym;
+
+ while (n) {
+ sym = rb_entry(n, struct symbol, rb_node);
+ n = rb_next(&sym->rb_node);
+ free(sym);
+ }
+}
+
static int btf_var_secinfo_cmp(const void *a, const void *b)
{
const struct btf_var_secinfo *av = a;
@@ -72,6 +157,7 @@ struct btf_elf *btf_elf__new(const char *filename, Elf *elf)
if (!btfe)
return NULL;
+ btfe->symbols = RB_ROOT;
btfe->in_fd = -1;
btfe->filename = strdup(filename);
if (btfe->filename == NULL)
@@ -177,6 +263,7 @@ void btf_elf__delete(struct btf_elf *btfe)
elf_end(btfe->elf);
}
+ btfe__delete_symbols(btfe);
elf_symtab__delete(btfe->symtab);
__gobuffer__delete(&btfe->percpu_secinfo);
btf__free(btfe->btf);
diff --git a/libbtf.h b/libbtf.h
index 887b5bc55c8e..f4a58834c390 100644
--- a/libbtf.h
+++ b/libbtf.h
@@ -12,6 +12,14 @@
#include <stdbool.h>
#include <stdint.h>
#include "lib/bpf/src/btf.h"
+#include "rbtree.h"
+
+struct symbol {
+ const char *name;
+ uint64_t addr;
+ bool generated;
+ struct rb_node rb_node;
+};
struct btf_elf {
void *priv;
@@ -27,6 +35,7 @@ struct btf_elf {
uint32_t percpu_shndx;
uint64_t percpu_base_addr;
struct btf *btf;
+ struct rb_root symbols;
};
extern uint8_t btf_elf__verbose;
@@ -66,4 +75,7 @@ int btf_elf__encode(struct btf_elf *btf, uint8_t flags);
const char *btf_elf__string(struct btf_elf *btf, uint32_t ref);
int btf_elf__load(struct btf_elf *btf);
+struct symbol *btfe__find_symbol(const struct btf_elf *btfe, const char *name);
+int btfe__load_symbols(struct btf_elf *btfe, struct cu *cu);
+
#endif /* _LIBBTF_H */
next prev parent reply other threads:[~2020-10-23 20:17 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1723352278.11013122.1600093319730.JavaMail.zimbra@redhat.com>
2020-09-14 14:48 ` Build failures: unresolved symbol vfs_getattr Veronika Kabatova
2020-09-14 18:25 ` Jiri Olsa
2020-09-14 22:26 ` Andrii Nakryiko
2020-09-15 7:30 ` Jiri Olsa
2020-09-15 12:17 ` Jiri Olsa
2020-09-16 9:06 ` Jiri Olsa
2020-10-16 21:38 ` Jiri Olsa
2020-10-21 19:42 ` Jiri Olsa
2020-10-22 20:00 ` Andrii Nakryiko
2020-10-23 5:36 ` Jiri Olsa
2020-10-23 6:58 ` Jiri Olsa
2020-10-23 18:22 ` Andrii Nakryiko
2020-10-23 20:17 ` Jiri Olsa [this message]
2020-10-23 20:32 ` Andrii Nakryiko
2020-10-23 20:45 ` Jiri Olsa
2020-10-23 22:02 ` Andrii Nakryiko
2020-10-26 10:14 ` Jiri Olsa
2020-10-26 22:06 ` Andrii Nakryiko
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=20201023201702.GA2495983@krava \
--to=jolsa@redhat.com \
--cc=acme@redhat.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andriin@fb.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=fche@redhat.com \
--cc=mjw@redhat.com \
--cc=vkabatov@redhat.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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox