btf: Support BTF_KIND_ENUM64

BTF_KIND_ENUM64 is supported with latest libbpf, which supports 64-bit
enum values. Latest libbpf also supports signedness for enum values. Add
enum64 support in dwarf-to-btf conversion.

The following is an example of new encoding which covers signed/unsigned
enum64/enum variations.

  $ cat t.c
  enum { /* signed, enum64 */
    A = -1,
    B = 0xffffffff,
  } g1;
  enum { /* unsigned, enum64 */
    C = 1,
    D = 0xfffffffff,
  } g2;
  enum { /* signed, enum */
    E = -1,
    F = 0xfffffff,
  } g3;
  enum { /* unsigned, enum */
    G = 1,
    H = 0xfffffff,
  } g4;
  $ clang -g -c t.c
  $ pahole -JV t.o
  btf_encoder__new: 't.o' doesn't have '.data..percpu' section
  Found 0 per-CPU variables!
  File t.o:
  [1] ENUM64 (anon) size=8
          A val=-1
          B val=4294967295
  [2] INT long size=8 nr_bits=64 encoding=SIGNED
  [3] ENUM64 (anon) size=8
          C val=1
          D val=68719476735
  [4] INT unsigned long size=8 nr_bits=64 encoding=(none)
  [5] ENUM (anon) size=4
          E val=-1
          F val=268435455
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  [7] ENUM (anon) size=4
          G val=1
          H val=268435455
  [8] INT unsigned int size=4 nr_bits=32 encoding=(none)

With the flag to skip enum64 encoding,

  $ pahole -JV t.o --skip_encoding_btf_enum64
  btf_encoder__new: 't.o' doesn't have '.data..percpu' section
  Found 0 per-CPU variables!
  File t.o:
  [1] ENUM (anon) size=8
        A val=4294967295
        B val=4294967295
  [2] INT long size=8 nr_bits=64 encoding=SIGNED
  [3] ENUM (anon) size=8
        C val=1
        D val=4294967295
  [4] INT unsigned long size=8 nr_bits=64 encoding=(none)
  [5] ENUM (anon) size=4
        E val=4294967295
        F val=268435455
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  [7] ENUM (anon) size=4
        G val=1
        H val=268435455
  [8] INT unsigned int size=4 nr_bits=32 encoding=(none)

In the above BTF encoding without enum64, all enum types with the same
type size as the corresponding enum64. All these enum types have
unsigned type (kflag = 0) which is required before kernel enum64
support.

Committer notes:

Add entry about --skip_encoding_btf_enum64 in the man page.

Committer testing:

  $ clang -g -c enum64.c

Before this patch:

  $ pahole -JV enum64.o
  btf_encoder__new: 'enum64.o' doesn't have '.data..percpu' section
  Found 0 per-CPU variables!
  File enum64.o:
  [1] ENUM (anon) size=8
	  A val=-1
	  B val=-1
  [2] INT long size=8 nr_bits=64 encoding=SIGNED
  [3] ENUM (anon) size=8
	  C val=1
	  D val=-1
  [4] INT unsigned long size=8 nr_bits=64 encoding=(none)
  [5] ENUM (anon) size=4
	  E val=-1
	  F val=268435455
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  [7] ENUM (anon) size=4
	  G val=1
	  H val=268435455
  [8] INT unsigned int size=4 nr_bits=32 encoding=(none)
  $

After:

  $ pahole -JV enum64.o
  btf_encoder__new: 'enum64.o' doesn't have '.data..percpu' section
  Found 0 per-CPU variables!
  File enum64.o:
  [1] ENUM64 (anon) size=8
  	A val=-1
  	B val=4294967295
  [2] INT long size=8 nr_bits=64 encoding=SIGNED
  [3] ENUM64 (anon) size=8
  	C val=1
  	D val=68719476735
  [4] INT unsigned long size=8 nr_bits=64 encoding=(none)
  [5] ENUM (anon) size=4
  	E val=-1
  	F val=268435455
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  [7] ENUM (anon) size=4
  	G val=1
  	H val=268435455
  [8] INT unsigned int size=4 nr_bits=32 encoding=(none)
  $

Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
7 files changed