From e33a74fb8c096bc190704402983acfeca25fc3ee Mon Sep 17 00:00:00 2001 From: "Guillermo E. Martinez" Date: Wed, 16 Nov 2022 21:43:04 -0600 Subject: [PATCH] ctf-reader: Fix representation of multidimensional arrays To build an IR for multidimensional array the CTF front-end iterates over the element types recursively. So, consider the array definition: char a[2][3][4][5]; It's represented as 'char[2][3][4] a[5]' instead of: 'char a[2][3][4][5]' It always considers multidimensional arrays as unidimensional creating a `array-type-def' node for each dimension: ... Instead of: ... Fixed thus. * src/abg-ctf-reader.cc (+build_array_ctf_range): New definition. * tests/data/Makefile.am: Add new testcase. * tests/data/test-read-ctf/test-array-mdimension.abi: New testcase. * tests/data/test-read-ctf/test-array-mdimension.c: Likewise. * tests/data/test-read-ctf/test-array-mdimension.o: Likewise. * tests/data/test-read-ctf/test9.o.abi: Adjust. * tests/test-read-ctf.cc: Update testsuite. Signed-off-by: Guillermo E. Martinez Signed-off-by: Dodji Seketeli --- src/abg-ctf-reader.cc | 101 +++++++++++++----- tests/data/Makefile.am | 3 + .../test-read-ctf/test-array-mdimension.abi | 16 +++ .../test-read-ctf/test-array-mdimension.c | 2 + .../test-read-ctf/test-array-mdimension.o | Bin 0 -> 1360 bytes tests/data/test-read-ctf/test9.o.abi | 36 +++---- tests/test-read-ctf.cc | 9 ++ 7 files changed, 120 insertions(+), 47 deletions(-) create mode 100644 tests/data/test-read-ctf/test-array-mdimension.abi create mode 100644 tests/data/test-read-ctf/test-array-mdimension.c create mode 100644 tests/data/test-read-ctf/test-array-mdimension.o diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index c48e61a4..b4b957d2 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc @@ -1163,6 +1163,57 @@ process_ctf_union_type(reader *rdr, return result; } +/// Build and return an array subrange. +/// +/// @param rdr the read context. +/// +/// @param ctf_dictionary the CTF dictionary where @ref index +/// will be found. +/// +/// @param index the CTF type ID for the array index. +/// +/// @param nelems the elements number of the array. +/// +/// @return a shared pointer to subrange built. +static array_type_def::subrange_sptr +build_array_ctf_range(reader *rdr, ctf_dict_t *dic, + ctf_id_t index, uint64_t nelems) +{ + bool is_infinite = false; + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); + array_type_def::subrange_sptr subrange; + array_type_def::subrange_type::bound_value lower_bound; + array_type_def::subrange_type::bound_value upper_bound; + + type_base_sptr index_type = rdr->build_type(dic, index); + if (!index_type) + return nullptr; + + lower_bound.set_unsigned(0); /* CTF supports C only. */ + upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U); + + /* for VLAs number of array elements is 0 */ + if (upper_bound.get_unsigned_value() == 0) + is_infinite = true; + + subrange.reset(new array_type_def::subrange_type(rdr->env(), + "", + lower_bound, + upper_bound, + index_type, + location(), + translation_unit::LANG_C)); + if (!subrange) + return nullptr; + + subrange->is_infinite(is_infinite); + add_decl_to_scope(subrange, tunit->get_global_scope()); + canonicalize(subrange); + + return subrange; +} + /// Build and return an array type libabigail IR. /// /// @param rdr the read context. @@ -1181,7 +1232,6 @@ process_ctf_array_type(reader *rdr, translation_unit_sptr tunit = rdr->cur_transl_unit(); array_type_def_sptr result; ctf_arinfo_t ctf_ainfo; - bool is_infinite = false; /* First, get the information about the CTF array. */ if (static_cast(ctf_array_info(ctf_dictionary, @@ -1192,6 +1242,26 @@ process_ctf_array_type(reader *rdr, ctf_id_t ctf_element_type = ctf_ainfo.ctr_contents; ctf_id_t ctf_index_type = ctf_ainfo.ctr_index; uint64_t nelems = ctf_ainfo.ctr_nelems; + array_type_def::subrange_sptr subrange; + array_type_def::subranges_type subranges; + + int type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type); + while (type_array_kind == CTF_K_ARRAY) + { + if (static_cast(ctf_array_info(ctf_dictionary, + ctf_element_type, + &ctf_ainfo)) == CTF_ERR) + return result; + + subrange = build_array_ctf_range(rdr, ctf_dictionary, + ctf_ainfo.ctr_index, + ctf_ainfo.ctr_nelems); + subranges.push_back(subrange); + ctf_element_type = ctf_ainfo.ctr_contents; + type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type); + } + + std::reverse(subranges.begin(), subranges.end()); /* Make sure the element type is generated. */ type_base_sptr element_type = rdr->build_type(ctf_dictionary, @@ -1210,33 +1280,8 @@ process_ctf_array_type(reader *rdr, if (result) return result; - /* The number of elements of the array determines the IR subranges - type to build. */ - array_type_def::subranges_type subranges; - array_type_def::subrange_sptr subrange; - array_type_def::subrange_type::bound_value lower_bound; - array_type_def::subrange_type::bound_value upper_bound; - - lower_bound.set_unsigned(0); /* CTF supports C only. */ - upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U); - - /* for VLAs number of array elements is 0 */ - if (upper_bound.get_unsigned_value() == 0) - is_infinite = true; - - subrange.reset(new array_type_def::subrange_type(rdr->env(), - "", - lower_bound, - upper_bound, - index_type, - location(), - translation_unit::LANG_C)); - if (!subrange) - return result; - - subrange->is_infinite(is_infinite); - add_decl_to_scope(subrange, tunit->get_global_scope()); - canonicalize(subrange); + subrange = build_array_ctf_range(rdr, ctf_dictionary, + ctf_index_type, nelems); subranges.push_back(subrange); /* Finally build the IR for the array type and return it. */ diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 8d4a2b8f..d04ecf3f 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -713,6 +713,9 @@ test-read-ctf/test-bitfield-enum.o \ test-read-ctf/test-const-array.abi \ test-read-ctf/test-const-array.c \ test-read-ctf/test-const-array.o \ +test-read-ctf/test-array-mdimension.abi \ +test-read-ctf/test-array-mdimension.c \ +test-read-ctf/test-array-mdimension.o \ \ test-annotate/test0.abi \ test-annotate/test1.abi \ diff --git a/tests/data/test-read-ctf/test-array-mdimension.abi b/tests/data/test-read-ctf/test-array-mdimension.abi new file mode 100644 index 00000000..177284d2 --- /dev/null +++ b/tests/data/test-read-ctf/test-array-mdimension.abi @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-array-mdimension.c b/tests/data/test-read-ctf/test-array-mdimension.c new file mode 100644 index 00000000..317fc589 --- /dev/null +++ b/tests/data/test-read-ctf/test-array-mdimension.c @@ -0,0 +1,2 @@ +/* gcc -gctf -c test-array-mdimension.c -o test-array-mdimension.o */ +char a[2][3][4][5]; diff --git a/tests/data/test-read-ctf/test-array-mdimension.o b/tests/data/test-read-ctf/test-array-mdimension.o new file mode 100644 index 0000000000000000000000000000000000000000..5b392d89439a1e39111c350ba2ee8baf7cdb4a14 GIT binary patch literal 1360 zcmbVM&2G~`5T3Ll{9P!g0vB_l6?pBWT<8H=s-OrVZX7wRoh7mGPqf~u@rhUH8^ELR z2)qH$051SD_N=`u;lfDcnf>Pbc6Y{3KD~JJa&IyLYZG`5CeM+!_aC%?gd2jdm`27QKp$WA$*H=~IBeZtUYq)jO6?Jfo4(1F9D03E*17)7=Y zr#ldrB3p-F!v*0KAzMogMP03ei>k?2m0AXQWk5o-u1giAZQ4e)mRX^qMrToxr!vh~ zGB3hPT}DPVriqr)$Sw`FlFKkNANrNlTDD=i%u9uP*OkZs&d<(HgQN4e?~a4{iHJoU zEaJstK98RTM{2uKn#e{L$Njwnz9$Os&XccBFF22Wz3ZJ(Yu2bfg&)7{+QxgB9KblW ztu0Vj;f~8o0MWFikts%_`?$85QCkCoW&t8?8W1=KeAFd11fr^q64*xA7@2+K^{ToM z8(m}DrnRU4cYJ_K>XpBtVV`8k{!IM2J;X9$<3xIX(ucpEzWxz1=)3)wewZ)s6mYcR z2`2uYR7>cA_S7qSOPC{vu$ah>874k - + + - - + + + - - - + + - - - - + - + - + - + - + - + - - + + - - + + diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index f2d529e2..f3d46118 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc @@ -372,6 +372,15 @@ static InOutSpec in_out_specs[] = "output/test-read-ctf/test-const-array.abi", "--ctf", }, + { + "data/test-read-ctf/test-array-mdimension.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-ctf/test-array-mdimension.abi", + "output/test-read-ctf/test-array-mdimension.abi", + "--ctf", + }, // This should be the last entry. {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL} }; -- 2.43.5