From: Alan Maguire <alan.maguire@oracle.com>
To: Stephen Brennan <stephen.s.brennan@oracle.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: dwarves@vger.kernel.org, linux-debuggers@vger.kernel.org
Subject: Re: [PATCH dwarves 3/4] btf_encoder: cache all ELF section info
Date: Fri, 13 Sep 2024 16:25:24 +0100 [thread overview]
Message-ID: <bf2a075b-1f30-475e-9d64-c96bbf646454@oracle.com> (raw)
In-Reply-To: <20240912190827.230176-4-stephen.s.brennan@oracle.com>
On 12/09/2024 20:08, Stephen Brennan wrote:
> To handle outputting all variables generally, we'll need to store more
> section data. Create a table of ELF sections so we can refer to all the
> cached data, not just the percpu section.
>
> Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
> ---
> btf_encoder.c | 50 ++++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 36 insertions(+), 14 deletions(-)
>
> diff --git a/btf_encoder.c b/btf_encoder.c
> index 8a2d92e..e3384e5 100644
> --- a/btf_encoder.c
> +++ b/btf_encoder.c
> @@ -65,12 +65,20 @@ struct elf_function {
> struct btf_encoder_state state;
> };
>
> +#define MAX_ELF_SEC_CNT 128
> +
> struct var_info {
> uint64_t addr;
> const char *name;
> uint32_t sz;
> };
>
> +struct elf_secinfo {
> + uint64_t addr;
> + const char *name;
> + uint64_t sz;
> +};
> +
One thing we've run into before is hardcoded limits get exceeded on
systems, and while it seems unlikely for 128 ELF sections, I think it'd
be better to make this dynamic just in case. Also for parallel mode we
have N encoders so it might same some memory (which we're pretty
profligate with in other areas). I'd suggest using reallocarray_grow()
as we do for functions. One thing we may want to tweak is that
reallocarray_grow() will grow by 1000 or 1.5 x the current size;
starting with 1000 ELF sections is a bit much. We could perhaps
tweak reallocarray_grow() to have a min_growth parameter to control this
and set it to something smaller for ELF sections, what do you think?
> /*
> * cu: cu being processed.
> */
> @@ -95,13 +103,13 @@ struct btf_encoder {
> is_rel,
> gen_distilled_base;
> uint32_t array_index_id;
> + struct elf_secinfo secinfo[MAX_ELF_SEC_CNT];
...so here we'd have a substructure like this
struct {
int allocated;
int sec_cnt;
struct elf_secinfo *sections;
} elf_sections;
> + size_t seccnt;
> struct {
> struct var_info *vars;
> int var_cnt;
> int allocated;
> uint32_t shndx;
> - uint64_t base_addr;
> - uint64_t sec_sz;
> } percpu;
> struct {
> struct elf_function *entries;
> @@ -1849,7 +1857,7 @@ static int btf_encoder__collect_percpu_var(struct btf_encoder *encoder, GElf_Sym
> * ET_EXEC file) we need to subtract the section address.
> */
> if (!encoder->is_rel)
> - addr -= encoder->percpu.base_addr;
> + addr -= encoder->secinfo[encoder->percpu.shndx].addr;
>
We will need some of these mechanics later when we encode function
addresses; great to have this!
> if (encoder->percpu.var_cnt == encoder->percpu.allocated) {
> struct var_info *new;
> @@ -1923,6 +1931,7 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder)
> uint32_t core_id;
> struct tag *pos;
> int err = -1;
> + struct elf_secinfo *pcpu_scn = &encoder->secinfo[encoder->percpu.shndx];
>
> if (encoder->percpu.shndx == 0 || !encoder->symtab)
> return 0;
> @@ -1954,9 +1963,9 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder)
> * always contains virtual symbol addresses, so subtract
> * the section address unconditionally.
> */
> - if (addr < encoder->percpu.base_addr || addr >= encoder->percpu.base_addr + encoder->percpu.sec_sz)
> + if (addr < pcpu_scn->addr || addr >= pcpu_scn->addr + pcpu_scn->sz)
> continue;
> - addr -= encoder->percpu.base_addr;
> + addr -= pcpu_scn->addr;
>
> if (!btf_encoder__percpu_var_exists(encoder, addr, &size, &name))
> continue; /* not a per-CPU variable */
> @@ -2099,20 +2108,33 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam
> goto out;
> }
>
> - /* find percpu section's shndx */
> + /* index the ELF sections for later lookup */
>
> GElf_Shdr shdr;
> - Elf_Scn *sec = elf_section_by_name(cu->elf, &shdr, PERCPU_SECTION, NULL);
> + size_t shndx;
> + if (elf_getshdrnum(cu->elf, &encoder->seccnt))
> + goto out_delete;
> + if (encoder->seccnt >= MAX_ELF_SEC_CNT) {
> + fprintf(stderr, "%s: reached limit of ELF sections\n", __func__);
> + goto out_delete;
> + }
>
as above we should just reallocarray_grow() more space.
> - if (!sec) {
> - if (encoder->verbose)
> - printf("%s: '%s' doesn't have '%s' section\n", __func__, cu->filename, PERCPU_SECTION);
> - } else {
> - encoder->percpu.shndx = elf_ndxscn(sec);
> - encoder->percpu.base_addr = shdr.sh_addr;
> - encoder->percpu.sec_sz = shdr.sh_size;
> + for (shndx = 0; shndx < encoder->seccnt; shndx++) {
> + const char *secname = NULL;
> + Elf_Scn *sec = elf_section_by_idx(cu->elf, &shdr, shndx, &secname);
> + if (!sec)
> + goto out_delete;
> + encoder->secinfo[shndx].addr = shdr.sh_addr;
> + encoder->secinfo[shndx].sz = shdr.sh_size;
> + encoder->secinfo[shndx].name = secname;
> +
> + if (strcmp(secname, PERCPU_SECTION) == 0)
> + encoder->percpu.shndx = shndx;
> }
>
> + if (!encoder->percpu.shndx && encoder->verbose)
> + printf("%s: '%s' doesn't have '%s' section\n", __func__, cu->filename, PERCPU_SECTION);
> +
> if (btf_encoder__collect_symbols(encoder, !encoder->skip_encoding_vars))
> goto out_delete;
>
next prev parent reply other threads:[~2024-09-13 15:25 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-12 19:08 [PATCH dwarves 0/4] Emit global variables in BTF Stephen Brennan
2024-09-12 19:08 ` [PATCH dwarves 1/4] dutil: return ELF section name when looked up by index Stephen Brennan
2024-09-13 13:26 ` Alan Maguire
2024-09-13 17:06 ` Stephen Brennan
2024-09-12 19:08 ` [PATCH dwarves 2/4] dwarf_loader: add "artificial" and "top_level" variable flags Stephen Brennan
2024-09-13 13:35 ` Alan Maguire
2024-09-13 17:16 ` Stephen Brennan
2024-09-12 19:08 ` [PATCH dwarves 3/4] btf_encoder: cache all ELF section info Stephen Brennan
2024-09-13 15:25 ` Alan Maguire [this message]
2024-09-13 17:05 ` Stephen Brennan
2024-09-15 11:26 ` Alan Maguire
2024-09-12 19:08 ` [PATCH dwarves 4/4] btf_encoder: add global_var feature to encode globals Stephen Brennan
2024-09-15 11:49 ` Alan Maguire
2024-09-20 8:18 ` Stephen Brennan
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=bf2a075b-1f30-475e-9d64-c96bbf646454@oracle.com \
--to=alan.maguire@oracle.com \
--cc=acme@kernel.org \
--cc=dwarves@vger.kernel.org \
--cc=linux-debuggers@vger.kernel.org \
--cc=stephen.s.brennan@oracle.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;
as well as URLs for NNTP newsgroup(s).