From: Jiri Olsa <jolsa@redhat.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Nathan Chancellor <nathan@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
Yonghong Song <yhs@fb.com>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Networking <netdev@vger.kernel.org>, bpf <bpf@vger.kernel.org>,
clang-built-linux <clang-built-linux@googlegroups.com>,
Veronika Kabatova <vkabatov@redhat.com>,
Jiri Olsa <jolsa@kernel.org>
Subject: Re: FAILED unresolved symbol vfs_truncate on arm64 with LLVM
Date: Thu, 11 Feb 2021 16:08:11 +0100 [thread overview]
Message-ID: <YCVIWzq0quDQm6bn@krava> (raw)
In-Reply-To: <YCQ+d0CVgIclDwng@krava>
On Wed, Feb 10, 2021 at 09:13:47PM +0100, Jiri Olsa wrote:
> On Wed, Feb 10, 2021 at 10:20:20AM -0800, Andrii Nakryiko wrote:
>
> SNIP
>
> > > but below is change for checking that ftrace addrs are within elf functions
> > >
> > > seems to work in my tests, I'll run some more tests and send full patch
> >
> > It seems unnecessarily convoluted. I was thinking about something like
> > this (the diff will totally be screwed up by gmail, and I haven't even
> > compiled it):
> >
> > diff --git a/btf_encoder.c b/btf_encoder.c
> > index b124ec20a689..8162b238bd43 100644
> > --- a/btf_encoder.c
> > +++ b/btf_encoder.c
> > @@ -236,6 +236,23 @@ get_kmod_addrs(struct btf_elf *btfe, __u64
> > **paddrs, __u64 *pcount)
> > return 0;
> > }
> >
> > +struct func_seg { __u64 start; __u64 end; };
> > +
> > +static int func_exists(struct func_seg *segs, size_t len, __u64 addr)
> > +{
> > + size_t l = 0, r = len - 1, m;
> > +
> > + while (l < r) {
> > + m = l + (r - l + 1) / 2;
> > + if (segs[m].start <= addr)
> > + l = m;
> > + else
> > + r = m - 1;
> > + }
> > +
> > + return segs[l].start <= addr && addr < segs[l].end;
> > +}
> > +
> > static int setup_functions(struct btf_elf *btfe, struct funcs_layout *fl)
> > {
> > __u64 *addrs, count, i;
> > @@ -286,7 +303,7 @@ static int setup_functions(struct btf_elf *btfe,
> > struct funcs_layout *fl)
> > __u64 addr = kmod ? func->addr + func->sh_addr : func->addr;
> >
> > /* Make sure function is within ftrace addresses. */
> > - if (bsearch(&addr, addrs, count, sizeof(addrs[0]), addrs_cmp)) {
> > + if (func_exists(addrs, count, addr))
>
> you pass addrs in here, but you mean func_seg array
> filled with elf functions start/end values, right?
>
> > /*
> > * We iterate over sorted array, so we can easily skip
> > * not valid item and move following valid field into
> >
> >
> > So the idea is to use address segments and check whether there is a
> > segment that overlaps with a given address by first binary searching
> > for a segment with the largest starting address that is <= addr. And
> > then just confirming that segment does overlap with the requested
> > address.
> >
> > WDYT?
heya,
with your approach I ended up with change below, it gives me same
results as with the previous change
I think I'll separate the kmod bool address computation later on,
but I did not want to confuse this change for now
jirka
---
diff --git a/btf_encoder.c b/btf_encoder.c
index b124ec20a689..34df08f2fb4e 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -36,6 +36,7 @@ struct funcs_layout {
struct elf_function {
const char *name;
unsigned long addr;
+ unsigned long end;
unsigned long sh_addr;
bool generated;
};
@@ -44,7 +45,7 @@ static struct elf_function *functions;
static int functions_alloc;
static int functions_cnt;
-static int functions_cmp(const void *_a, const void *_b)
+static int functions_cmp_name(const void *_a, const void *_b)
{
const struct elf_function *a = _a;
const struct elf_function *b = _b;
@@ -52,6 +53,16 @@ static int functions_cmp(const void *_a, const void *_b)
return strcmp(a->name, b->name);
}
+static int functions_cmp_addr(const void *_a, const void *_b)
+{
+ const struct elf_function *a = _a;
+ const struct elf_function *b = _b;
+
+ if (a->addr == b->addr)
+ return 0;
+ return a->addr < b->addr ? -1 : 1;
+}
+
static void delete_functions(void)
{
free(functions);
@@ -98,6 +109,7 @@ static int collect_function(struct btf_elf *btfe, GElf_Sym *sym,
functions[functions_cnt].name = name;
functions[functions_cnt].addr = elf_sym__value(sym);
+ functions[functions_cnt].end = (__u64) -1;
functions[functions_cnt].sh_addr = sh.sh_addr;
functions[functions_cnt].generated = false;
functions_cnt++;
@@ -236,6 +248,40 @@ get_kmod_addrs(struct btf_elf *btfe, __u64 **paddrs, __u64 *pcount)
return 0;
}
+static int is_ftrace_func(struct elf_function *func, __u64 *addrs,
+ __u64 count, bool kmod)
+{
+ /*
+ * For vmlinux image both addrs[x] and functions[x]::addr
+ * values are final address and are comparable.
+ *
+ * For kernel module addrs[x] is final address, but
+ * functions[x]::addr is relative address within section
+ * and needs to be relocated by adding sh_addr.
+ */
+ __u64 start = kmod ? func->addr + func->sh_addr : func->addr;
+ __u64 end = kmod ? func->end + func->sh_addr : func->end;
+
+ size_t l = 0, r = count - 1, m;
+ __u64 addr = 0;
+
+ while (l < r) {
+ m = l + (r - l + 1) / 2;
+ addr = addrs[m];
+
+ if (start <= addr && addr < end)
+ return true;
+
+ if (start <= addr)
+ r = m - 1;
+ else
+ l = m;
+ }
+
+ addr = addrs[l];
+ return start <= addr && addr < end;
+}
+
static int setup_functions(struct btf_elf *btfe, struct funcs_layout *fl)
{
__u64 *addrs, count, i;
@@ -267,7 +313,7 @@ static int setup_functions(struct btf_elf *btfe, struct funcs_layout *fl)
}
qsort(addrs, count, sizeof(addrs[0]), addrs_cmp);
- qsort(functions, functions_cnt, sizeof(functions[0]), functions_cmp);
+ qsort(functions, functions_cnt, sizeof(functions[0]), functions_cmp_addr);
/*
* Let's got through all collected functions and filter
@@ -275,18 +321,12 @@ static int setup_functions(struct btf_elf *btfe, struct funcs_layout *fl)
*/
for (i = 0; i < functions_cnt; i++) {
struct elf_function *func = &functions[i];
- /*
- * For vmlinux image both addrs[x] and functions[x]::addr
- * values are final address and are comparable.
- *
- * For kernel module addrs[x] is final address, but
- * functions[x]::addr is relative address within section
- * and needs to be relocated by adding sh_addr.
- */
- __u64 addr = kmod ? func->addr + func->sh_addr : func->addr;
+
+ if (i + 1 < functions_cnt)
+ func->end = functions[i + 1].addr;
/* Make sure function is within ftrace addresses. */
- if (bsearch(&addr, addrs, count, sizeof(addrs[0]), addrs_cmp)) {
+ if (is_ftrace_func(func, addrs, count, kmod)) {
/*
* We iterate over sorted array, so we can easily skip
* not valid item and move following valid field into
@@ -303,6 +343,8 @@ static int setup_functions(struct btf_elf *btfe, struct funcs_layout *fl)
if (btf_elf__verbose)
printf("Found %d functions!\n", functions_cnt);
+
+ qsort(functions, functions_cnt, sizeof(functions[0]), functions_cmp_name);
return 0;
}
@@ -312,7 +354,7 @@ static struct elf_function *find_function(const struct btf_elf *btfe,
struct elf_function key = { .name = name };
return bsearch(&key, functions, functions_cnt, sizeof(functions[0]),
- functions_cmp);
+ functions_cmp_name);
}
static bool btf_name_char_ok(char c, bool first)
next prev parent reply other threads:[~2021-02-11 15:19 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-09 3:44 FAILED unresolved symbol vfs_truncate on arm64 with LLVM Nathan Chancellor
2021-02-09 4:45 ` Andrii Nakryiko
2021-02-09 5:23 ` Nathan Chancellor
2021-02-09 6:09 ` Andrii Nakryiko
2021-02-09 6:13 ` Andrii Nakryiko
2021-02-09 6:56 ` Andrii Nakryiko
2021-02-09 7:49 ` Nathan Chancellor
2021-02-09 12:36 ` Jiri Olsa
2021-02-09 15:09 ` Jiri Olsa
2021-02-09 16:13 ` Jiri Olsa
2021-02-09 16:35 ` Nathan Chancellor
2021-02-09 17:07 ` Sedat Dilek
2021-02-09 17:12 ` Nick Desaulniers
2021-02-09 17:26 ` Sedat Dilek
2021-02-09 19:06 ` Jiri Olsa
2021-02-09 19:22 ` Jiri Olsa
2021-02-09 20:09 ` Nick Desaulniers
2021-02-09 20:50 ` Jiri Olsa
2021-02-09 21:41 ` Jiri Olsa
2021-02-09 23:15 ` Nathan Chancellor
2021-02-10 0:02 ` Nathan Chancellor
2021-02-10 0:49 ` Daniel Kiss
2021-02-10 11:34 ` David Laight
2021-02-10 12:32 ` Jiri Olsa
2021-02-09 20:59 ` Andrii Nakryiko
2021-02-09 21:55 ` Jiri Olsa
2021-02-09 22:00 ` Andrii Nakryiko
2021-02-10 13:26 ` Jiri Olsa
2021-02-10 18:02 ` Nathan Chancellor
2021-02-10 18:20 ` Andrii Nakryiko
2021-02-10 18:24 ` Sedat Dilek
2021-02-10 19:10 ` Jiri Olsa
2021-02-10 19:21 ` Andrii Nakryiko
2021-02-10 20:13 ` Jiri Olsa
2021-02-11 15:08 ` Jiri Olsa [this message]
2021-02-11 15:43 ` Sedat Dilek
2021-02-11 16:07 ` Jiri Olsa
2021-02-11 16:36 ` Sedat Dilek
2021-02-11 17:24 ` Nathan Chancellor
2021-02-11 19:59 ` Andrii Nakryiko
2021-02-11 21:47 ` Jiri Olsa
2021-02-12 16:38 ` Jiri Olsa
2021-02-12 19:22 ` Andrii Nakryiko
2021-02-12 21:29 ` Jiri Olsa
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=YCVIWzq0quDQm6bn@krava \
--to=jolsa@redhat.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=clang-built-linux@googlegroups.com \
--cc=daniel@iogearbox.net \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kafai@fb.com \
--cc=kpsingh@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=netdev@vger.kernel.org \
--cc=songliubraving@fb.com \
--cc=vkabatov@redhat.com \
--cc=yhs@fb.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.