Re: [PATCH v2 0/1] btf_loader support for subprogram linkage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 27, 2024 at 10:37 AM Arnaldo Carvalho de Melo
<acme@xxxxxxxxxx> wrote:
>
> On Tue, Aug 27, 2024 at 12:09:07AM -0400, Will Hawkins wrote:
> > Thank you for the feedback on my first attempt. I believe that this
> > attempt is better. Given the feedback, I
> >
> > 0. Removed the incorrect use of linkage_name field;
> > 1. Tried to maintain the semantics of DWARF as much as possible;
> > 2. Reworked how BTF information is loaded into a new function based on
> > my understanding of the semantics of BTF_FUNC_STATIC, BTF_FUNC_GLOBAL,
> > and BTF_FUNC_EXTERN; and
> > 3. Modified (slightly) the way functions are printed in pfunc to show
> > linkage where appropriate (based, in particular, on
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45153#c6.
> >
> > I saw that Arnaldo and Namhyung have made similar changes to the
> > printing code so I hope that I am not stepping on their work (sorry if I
> > am!).
> >
> > Again, I appreciate the feedback and hope that I was able to address it
> > with this v2.
>
> So, I broke it down into two patches, the first for the BTF loader and
> then a second patch for pfunct to use that info, but:
>
> ⬢[acme@toolbox pahole]$ readelf -wi cases/btf_linkages/linkage.o
> Contents of the .debug_info section:
>
>   Compilation Unit @ offset 0:
>    Length:        0x4e (32-bit)
>    Version:       5
>    Unit Type:     DW_UT_compile (1)
>    Abbrev Offset: 0
>    Pointer Size:  8
>  <0><c>: Abbrev Number: 1 (DW_TAG_compile_unit)
>     <d>   DW_AT_producer    : (indirect string, offset: 0x5): GNU C17 14.1.1 20240701 (Red Hat 14.1.1-7) -mtune=generic -march=x86-64 -gbtf -g -O0
>     <11>   DW_AT_language    : 29       (C11)
>     <12>   DW_AT_name        : (indirect line string, offset: 0): linkage.c
>     <16>   DW_AT_comp_dir    : (indirect line string, offset: 0xa): /home/acme/git/pahole/cases/btf_linkages
>     <1a>   DW_AT_low_pc      : 0
>     <22>   DW_AT_high_pc     : 0xb
>     <2a>   DW_AT_stmt_list   : 0
>  <1><2e>: Abbrev Number: 2 (DW_TAG_subprogram)
>     <2f>   DW_AT_name        : x
>     <31>   DW_AT_decl_file   : 1
>     <32>   DW_AT_decl_line   : 6
>     <33>   DW_AT_decl_column : 12
>     <34>   DW_AT_type        : <0x4a>
>     <38>   DW_AT_low_pc      : 0
>     <40>   DW_AT_high_pc     : 0xb
>     <48>   DW_AT_frame_base  : 1 byte block: 9c         (DW_OP_call_frame_cfa)
>     <4a>   DW_AT_call_all_calls: 1
>  <1><4a>: Abbrev Number: 3 (DW_TAG_base_type)
>     <4b>   DW_AT_byte_size   : 4
>     <4c>   DW_AT_encoding    : 5        (signed)
>     <4d>   DW_AT_name        : int
>  <1><51>: Abbrev Number: 0
>
> ⬢[acme@toolbox pahole]$
>
> In DWARF we don't have that DW_AT_external, so the simplified second
> patch:
>
> ⬢[acme@toolbox pahole]$ git diff
> diff --git a/pfunct.c b/pfunct.c
> index bc3026b384284cb4..9cf61713354d178e 100644
> --- a/pfunct.c
> +++ b/pfunct.c
> @@ -377,6 +377,9 @@ static void function__show(struct function *func, struct cu *cu)
>         if (fstats && fstats->printed)
>                 return;
>
> +       if (!func->external)
> +               fprintf(stdout, "static ");
> +
>         if (expand_types)
>                 function__emit_type_definitions(func, cu, stdout);
>         tag__fprintf(tag, cu, &conf, stdout);
> ⬢[acme@toolbox pahole]$
>
> Would print as static, but it isn't...
>
> ⬢[acme@toolbox pahole]$ cat cases/btf_linkages/linkage.c
> // https://lore.kernel.org/all/20240823212835.1078351-1-hawkinsw@xxxxxx/T/#u
> // Will Hawkins
> // $ gcc -gbtf -g -O0 -c linkage.c
> // $ ~/code/pahole/build/pfunct -Fbtf --compile linkage.o
>
> static int x() {
>         return 5;
> }
> ⬢[acme@toolbox pahole]$
>
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf cases/btf_linkages/linkage.o
> int x(void);
> ⬢[acme@toolbox pahole]$
>

Sorry for the trouble! I *thought* that I tested cases like these and
got results that seemed reasonable. Clearly what you got does not seem
to work. So, I will go through and test using a few different cases,
make sure that I get the right answer, then confirm with you in a
follow-up patch.

(See below)

>
> So, if instead I do it at:
>
> ⬢[acme@toolbox pahole]$ git diff
> diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c
> index ffbe6fbd3f5c405a..9a8bb5f15c88125a 100644
> --- a/dwarves_fprintf.c
> +++ b/dwarves_fprintf.c
> @@ -1406,6 +1406,9 @@ static size_t function__fprintf(const struct tag *tag, const struct cu *cu,
>         size_t printed = 0;
>         bool inlined = !conf->strip_inline && function__declared_inline(func);
>
> +       if (!func->external)
> +               printed += fprintf(fp, "%s ", "static");
> +
>         if (tag->attribute)
>                 printed += fprintf(fp, "%s ", tag->attribute);
>
> ⬢[acme@toolbox pahole]$
>
> Then we seem to get what we want:
>
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf cases/btf_linkages/linkage.o
> static int x(void);
> ⬢[acme@toolbox pahole]$ pfunct --compile -F btf cases/btf_linkages/linkage.o
> static int x(void)
> {
>         return 0;
> }
>
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F dwarf cases/btf_linkages/linkage.o
> static int x(void);
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf cases/btf_linkages/linkage.o
> static int x(void);
> ⬢[acme@toolbox pahole]$
>
> And if we add a non-static function, it also works for both DWARF and
> BTF when generated by gcc:
>
> ⬢[acme@toolbox btf_linkages]$ gcc -gbtf -g -O0 -c linkage.c
> ⬢[acme@toolbox btf_linkages]$ cd -
> /home/acme/git/pahole
> ⬢[acme@toolbox pahole]$ cat cases/btf_linkages/linkage.c
> // https://lore.kernel.org/all/20240823212835.1078351-1-hawkinsw@xxxxxx/T/#u
> // Will Hawkins
> // $ gcc -gbtf -g -O0 -c linkage.c
> // $ ~/code/pahole/build/pfunct -Fbtf --compile linkage.o
>
> static int x() {
>         return 5;
> }
>
> int y() {
>         return 4;
> }
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf cases/btf_linkages/linkage.o
> static int x(void);
> int y(void);
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F dwarf cases/btf_linkages/linkage.o
> static int x(void);
> int y(void);
> ⬢[acme@toolbox pahole]$ pfunct --compile -F btf cases/btf_linkages/linkage.o
> int y(void)
> {
>         return 0;
> }
>
> static int x(void)
> {
>         return 0;
> }
>
> ⬢[acme@toolbox pahole]$ pfunct --compile -F dwarf cases/btf_linkages/linkage.o
> int y(void)
> {
> }
>
> static int x(void)
> {
> }
>
> ⬢[acme@toolbox pahole]$
>
> But, for a vmlinux I have laying around it seems we're not encoding that
> with pahole:
>
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf vmlinux  | grep ^static | head
> static void clean_cache_range(void * addr, size_t size);
> static void arch_wb_cache_pmem(void * addr, size_t size);
> static long int __copy_user_flushcache(void * dst, const void  * src, unsigned int size);
> static void __memcpy_flushcache(void * _dst, const void  * _src, size_t size);
> static long unsigned int copy_from_user_nmi(void * to, const void  * from, long unsigned int n);
> static void call_depth_return_thunk(void);
> static void entry_untrain_ret(void);
> static void retbleed_untrain_ret(void);
> static void srso_untrain_ret(void);
> static void srso_alias_safe_ret(void);
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf vmlinux  | grep ^static | wc -l
> 59015
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf vmlinux  | wc -l
> 59015
> ⬢[acme@toolbox pahole]$
>
> ⬢[acme@toolbox pahole]$ pahole --btf_encode -j vmlinux
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf vmlinux  | wc -l
> 59650
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf vmlinux  | grep ^static | wc -l
> 59650
> ⬢[acme@toolbox pahole]$ pfunct --prototype -F btf vmlinux  | grep -v ^static
> ⬢[acme@toolbox pahole]$
>
> So before we change function__fprintf() we need to investigate this
> other part: pahole seemingly not encoding:
>
> +       func->declaration = BTF_INFO_VLEN(tp->info) == BTF_FUNC_EXTERN;
> +       func->external = BTF_INFO_VLEN(tp->info) == BTF_FUNC_GLOBAL;
>
> The thing is we want to release 1.28, so lets leave this for after that,
> ok.

Sorry -- it took me a few reads through your thorough email to
understand. I appreciate your willingness to engage with me on this
patch! If I understand correctly, you are saying that pahole may not
be encoding the BTF_FUNC* properly. So, we will need to debug that at
the same time as we add this feature.

If that is the case, then I will start to work on that!

If possible, would you be willing to send around that "bad" vmlinux?
(You can send directly to me -- I know that they are far from small).
That would help me debug and recreate what you are seeing.

Thank you again for engaging with me on this effort! I really, really
appreciate your openness! As I said, I am a huge fan of your work (I
really enjoyed your talk at DevConf in 2021)!

Will

>
> - Arnaldo





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux