btf_encoder: Fix emitting __ARRAY_SIZE_TYPE__ as index range type

Fix the logic of determining if __ARRAY_SIZE_TYPE__ needs to be emitted.
Previously, such type could be emitted unnecessarily due to some
particular CU not having an int type in it. That would happen even if
there was no array type in that CU. Fix it by keeping track of 'int'
type across CUs and only emitting __ARRAY_SIZE_TYPE__ if a given CU has
array type, but we still haven't found 'int' type.

Testing against vmlinux shows that now there are no __ARRAY_SIZE_TYPE__
integers emitted.

Committer testing:

  $ pahole -J vmlinux
  $ ./btfdiff vmlinux
  $

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
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>
This commit is contained in:
Andrii Nakryiko 2020-10-08 16:39:55 -07:00 committed by Arnaldo Carvalho de Melo
parent 48efa92933
commit 3c913e18b2
1 changed files with 21 additions and 9 deletions

View File

@ -147,6 +147,8 @@ static int32_t enumeration_type__encode(struct btf_elf *btfe, struct cu *cu, str
return type_id;
}
static bool need_index_type;
static int tag__encode_btf(struct cu *cu, struct tag *tag, uint32_t core_id, struct btf_elf *btfe,
uint32_t array_index_id, uint32_t type_id_off)
{
@ -179,6 +181,7 @@ static int tag__encode_btf(struct cu *cu, struct tag *tag, uint32_t core_id, str
return structure_type__encode(btfe, cu, tag, type_id_off);
case DW_TAG_array_type:
/* TODO: Encode one dimension at a time. */
need_index_type = true;
return btf_elf__add_array(btfe, ref_type_id, array_index_id, array_type__nelems(tag));
case DW_TAG_enumeration_type:
return enumeration_type__encode(btfe, cu, tag);
@ -193,6 +196,7 @@ static int tag__encode_btf(struct cu *cu, struct tag *tag, uint32_t core_id, str
static struct btf_elf *btfe;
static uint32_t array_index_id;
static bool has_index_type;
int btf_encoder__encode()
{
@ -228,7 +232,6 @@ static struct variable *hashaddr__find_variable(const struct hlist_head hashtabl
int cu__encode_btf(struct cu *cu, int verbose, bool force,
bool skip_encoding_vars)
{
bool add_index_type = false;
uint32_t type_id_off;
uint32_t core_id;
struct function *fn;
@ -254,18 +257,26 @@ int cu__encode_btf(struct cu *cu, int verbose, bool force,
if (!btfe)
return -1;
/* cu__find_base_type_by_name() takes "type_id_t *id" */
type_id_t id;
if (!cu__find_base_type_by_name(cu, "int", &id)) {
add_index_type = true;
id = cu->types_table.nr_entries;
}
array_index_id = id;
has_index_type = false;
need_index_type = false;
array_index_id = 0;
if (verbose)
printf("File %s:\n", btfe->filename);
}
if (!has_index_type) {
/* cu__find_base_type_by_name() takes "type_id_t *id" */
type_id_t id;
if (cu__find_base_type_by_name(cu, "int", &id)) {
has_index_type = true;
array_index_id = id;
} else {
has_index_type = false;
array_index_id = cu->types_table.nr_entries;
}
}
btf_elf__verbose = verbose;
type_id_off = btf__get_nr_types(btfe->btf);
@ -279,12 +290,13 @@ int cu__encode_btf(struct cu *cu, int verbose, bool force,
}
}
if (add_index_type) {
if (need_index_type && !has_index_type) {
struct base_type bt = {};
bt.name = 0;
bt.bit_size = 32;
btf_elf__add_base_type(btfe, &bt, "__ARRAY_SIZE_TYPE__");
has_index_type = true;
}
cu__for_each_function(cu, core_id, fn) {