diff options
author | Guillermo E. Martinez via Libabigail <libabigail@sourceware.org> | 2022-03-17 19:30:36 -0600 |
---|---|---|
committer | Dodji Seketeli <dodji@redhat.com> | 2022-04-29 12:46:33 +0200 |
commit | 6716aa042bc84f79ae5292fc24d435048e26e078 (patch) | |
tree | aa93c6c70cb8f61500754cdcc3b254a763b52572 | |
parent | comparison: Avoid sorting diff nodes with wrong criteria (diff) | |
download | libabigail-6716aa042bc84f79ae5292fc24d435048e26e078.tar.gz libabigail-6716aa042bc84f79ae5292fc24d435048e26e078.tar.bz2 libabigail-6716aa042bc84f79ae5292fc24d435048e26e078.tar.xz |
ctf-reader: Add support to undefined forward declaration types
Undefined struct/union forward declaration types are not serialized in
abixml representation using `class-decl' node.
For instance, consider:
struct key_type;
typedef void (*key_restrict_link_func_t)(struct key_type *type);
Expected node:
<class-decl name='key_type' ... is-declaration-only='yes'.../>
* src/abg-ctf-reader.cc (process_ctf_forward_type): New
function.
(process_ctf_type): New CTF_K_FORWARD case.
* tests/data/test-read-ctf/test-forward-undefine-type-decl.c:
New testcase.
* tests/data/test-read-ctf/test-forward-undefine-type-decl.abi:
New expected result.
* tests/data/test-read-ctf/test-forward-undefine-type-decl.o
New test input.
* tests/test-read-ctf.cc: Add new testcase to test harness.
* tests/data/Makefile.am: Add new test input files to test harness.
Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
-rw-r--r-- | src/abg-ctf-reader.cc | 62 | ||||
-rw-r--r-- | tests/data/Makefile.am | 3 | ||||
-rw-r--r-- | tests/data/test-read-ctf/test-forward-undefine-type-decl.abi | 31 | ||||
-rw-r--r-- | tests/data/test-read-ctf/test-forward-undefine-type-decl.c | 17 | ||||
-rw-r--r-- | tests/data/test-read-ctf/test-forward-undefine-type-decl.o | bin | 0 -> 1488 bytes | |||
-rw-r--r-- | tests/test-read-ctf.cc | 8 |
6 files changed, 121 insertions, 0 deletions
diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index e5ea0ca2..f8cdf6be 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc | |||
@@ -384,6 +384,61 @@ process_ctf_sou_members(read_context *ctxt, | |||
384 | fprintf(stderr, "ERROR from ctf_member_next\n"); | 384 | fprintf(stderr, "ERROR from ctf_member_next\n"); |
385 | } | 385 | } |
386 | 386 | ||
387 | /// Create a declaration-only union or struct type and add it to the | ||
388 | /// IR. | ||
389 | /// | ||
390 | /// @param ctxt the read context. | ||
391 | /// @param tunit the current IR translation unit. | ||
392 | /// @param ctf_dictionary the CTF dictionary being read. | ||
393 | /// @param ctf_type the CTF type ID of the source type. | ||
394 | /// @return the resulting IR node created. | ||
395 | |||
396 | static type_base_sptr | ||
397 | process_ctf_forward_type(read_context *ctxt, | ||
398 | translation_unit_sptr tunit, | ||
399 | ctf_dict_t *ctf_dictionary, | ||
400 | ctf_id_t ctf_type) | ||
401 | { | ||
402 | decl_base_sptr result; | ||
403 | std::string type_name = ctf_type_name_raw(ctf_dictionary, | ||
404 | ctf_type); | ||
405 | bool type_is_anonymous = (type_name == ""); | ||
406 | uint32_t kind = ctf_type_kind_forwarded (ctf_dictionary, ctf_type); | ||
407 | |||
408 | if (kind == CTF_K_UNION) | ||
409 | { | ||
410 | union_decl_sptr | ||
411 | union_fwd(new union_decl(ctxt->ir_env, | ||
412 | type_name, | ||
413 | /*alignment=*/0, | ||
414 | location(), | ||
415 | decl_base::VISIBILITY_DEFAULT, | ||
416 | type_is_anonymous)); | ||
417 | union_fwd->set_is_declaration_only(true); | ||
418 | result = union_fwd; | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | class_decl_sptr | ||
423 | struct_fwd(new class_decl(ctxt->ir_env, type_name, | ||
424 | /*alignment=*/0, /*size=*/0, | ||
425 | true /* is_struct */, | ||
426 | location(), | ||
427 | decl_base::VISIBILITY_DEFAULT, | ||
428 | type_is_anonymous)); | ||
429 | struct_fwd->set_is_declaration_only(true); | ||
430 | result = struct_fwd; | ||
431 | } | ||
432 | |||
433 | if (!result) | ||
434 | return is_type(result); | ||
435 | |||
436 | add_decl_to_scope(result, tunit->get_global_scope()); | ||
437 | ctxt->add_type(ctf_type, is_type(result)); | ||
438 | |||
439 | return is_type(result); | ||
440 | } | ||
441 | |||
387 | /// Build and return a struct type libabigail IR. | 442 | /// Build and return a struct type libabigail IR. |
388 | /// | 443 | /// |
389 | /// @param ctxt the read context. | 444 | /// @param ctxt the read context. |
@@ -813,6 +868,13 @@ process_ctf_type(read_context *ctxt, | |||
813 | result = is_type(struct_decl); | 868 | result = is_type(struct_decl); |
814 | break; | 869 | break; |
815 | } | 870 | } |
871 | case CTF_K_FORWARD: | ||
872 | { | ||
873 | result = process_ctf_forward_type(ctxt, tunit, | ||
874 | ctf_dictionary, | ||
875 | ctf_type); | ||
876 | } | ||
877 | break; | ||
816 | case CTF_K_UNION: | 878 | case CTF_K_UNION: |
817 | { | 879 | { |
818 | union_decl_sptr union_decl | 880 | union_decl_sptr union_decl |
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index a7eb7ff0..8f71fcbf 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am | |||
@@ -660,6 +660,9 @@ test-read-ctf/test-functions-declaration.o \ | |||
660 | test-read-ctf/test-forward-type-decl.abi \ | 660 | test-read-ctf/test-forward-type-decl.abi \ |
661 | test-read-ctf/test-forward-type-decl.o \ | 661 | test-read-ctf/test-forward-type-decl.o \ |
662 | test-read-ctf/test-forward-type-decl.c \ | 662 | test-read-ctf/test-forward-type-decl.c \ |
663 | test-read-ctf/test-forward-undefine-type-decl.abi \ | ||
664 | test-read-ctf/test-forward-undefine-type-decl.c \ | ||
665 | test-read-ctf/test-forward-undefine-type-decl.o \ | ||
663 | test-read-ctf/test-list-struct.c \ | 666 | test-read-ctf/test-list-struct.c \ |
664 | test-read-ctf/test-list-struct.o \ | 667 | test-read-ctf/test-list-struct.o \ |
665 | test-read-ctf/test-list-struct.abi \ | 668 | test-read-ctf/test-list-struct.abi \ |
diff --git a/tests/data/test-read-ctf/test-forward-undefine-type-decl.abi b/tests/data/test-read-ctf/test-forward-undefine-type-decl.abi new file mode 100644 index 00000000..ff019208 --- /dev/null +++ b/tests/data/test-read-ctf/test-forward-undefine-type-decl.abi | |||
@@ -0,0 +1,31 @@ | |||
1 | <abi-corpus version='2.1' path='data/test-read-ctf/test-forward-undefine-type-decl.o'> | ||
2 | <elf-variable-symbols> | ||
3 | <elf-symbol name='k' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> | ||
4 | </elf-variable-symbols> | ||
5 | <abi-instr address-size='64' language='LANG_C'> | ||
6 | <class-decl name='key_restriction' size-in-bits='192' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'> | ||
7 | <data-member access='public' layout-offset-in-bits='0'> | ||
8 | <var-decl name='check' type-id='type-id-2' visibility='default'/> | ||
9 | </data-member> | ||
10 | <data-member access='public' layout-offset-in-bits='64'> | ||
11 | <var-decl name='keytype' type-id='type-id-3' visibility='default'/> | ||
12 | </data-member> | ||
13 | <data-member access='public' layout-offset-in-bits='128'> | ||
14 | <var-decl name='keyutype' type-id='type-id-4' visibility='default'/> | ||
15 | </data-member> | ||
16 | </class-decl> | ||
17 | <typedef-decl name='key_restrict_link_func_t' type-id='type-id-5' id='type-id-2'/> | ||
18 | <pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/> | ||
19 | <pointer-type-def type-id='type-id-7' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/> | ||
20 | <pointer-type-def type-id='type-id-8' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/> | ||
21 | <class-decl name='key_type' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-6'/> | ||
22 | <var-decl name='k' type-id='type-id-1' mangled-name='k' visibility='default'/> | ||
23 | <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-8'> | ||
24 | <parameter type-id='type-id-3'/> | ||
25 | <parameter type-id='type-id-4'/> | ||
26 | <return type-id='type-id-9'/> | ||
27 | </function-type> | ||
28 | <union-decl name='key_utype' visibility='default' is-declaration-only='yes' id='type-id-7'/> | ||
29 | <type-decl name='void' id='type-id-9'/> | ||
30 | </abi-instr> | ||
31 | </abi-corpus> | ||
diff --git a/tests/data/test-read-ctf/test-forward-undefine-type-decl.c b/tests/data/test-read-ctf/test-forward-undefine-type-decl.c new file mode 100644 index 00000000..b6ab4896 --- /dev/null +++ b/tests/data/test-read-ctf/test-forward-undefine-type-decl.c | |||
@@ -0,0 +1,17 @@ | |||
1 | /* Test undefined forward declarations | ||
2 | * gcc -gctf -c test-forward-undefine-type-decl.c -o \ | ||
3 | * test-forward-undefine-type-decl.o | ||
4 | */ | ||
5 | |||
6 | struct key_type; | ||
7 | union key_utype; | ||
8 | typedef void (*key_restrict_link_func_t)(struct key_type *type, | ||
9 | union key_utype *utype); | ||
10 | |||
11 | struct key_restriction { | ||
12 | key_restrict_link_func_t check; | ||
13 | struct key_type *keytype; | ||
14 | union key_utype *keyutype; | ||
15 | }; | ||
16 | |||
17 | struct key_restriction k; | ||
diff --git a/tests/data/test-read-ctf/test-forward-undefine-type-decl.o b/tests/data/test-read-ctf/test-forward-undefine-type-decl.o new file mode 100644 index 00000000..e8adc144 --- /dev/null +++ b/tests/data/test-read-ctf/test-forward-undefine-type-decl.o | |||
Binary files differ | |||
diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index e7a87186..8ed8ac1a 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc | |||
@@ -268,6 +268,14 @@ static InOutSpec in_out_specs[] = | |||
268 | "data/test-read-ctf/test-callback2.abi", | 268 | "data/test-read-ctf/test-callback2.abi", |
269 | "output/test-read-ctf/test-callback2.abi", | 269 | "output/test-read-ctf/test-callback2.abi", |
270 | }, | 270 | }, |
271 | { | ||
272 | "data/test-read-ctf/test-forward-undefine-type-decl.o", | ||
273 | "", | ||
274 | "", | ||
275 | SEQUENCE_TYPE_ID_STYLE, | ||
276 | "data/test-read-ctf/test-forward-undefine-type-decl.abi", | ||
277 | "output/test-read-ctf/test-forward-undefine-type-decl.abi", | ||
278 | }, | ||
271 | // This should be the last entry. | 279 | // This should be the last entry. |
272 | {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} | 280 | {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} |
273 | }; | 281 | }; |