mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-15 14:34:38 +00:00
ctf-reader: Assert on ir::hash_as_canonical_type_or_constant
In some scenarios where we declare same data types `recursively' such as: like linked list, functions that accept the same pointer to function as arguments, forward types declarations to build structures with member fields with mutual dependencies, etc., an assertion is trigger: abidw: ../../../libabigail-upstream/src/abg-ir.cc:25251: size_t abigail::ir::hash_as_canonical_type_or_constant(const abigail::ir::type_base*): Assertion `__abg_cond__' failed. It is happening because the recursively behavior of `process_ctf_type' and `process_ctf_*' used to register ctf types doesn't verify when a ctf_type was processed and registered before by their subsequence _recursive_ calls, so `type_base' object is built more than once and the second time when it is inserted in `types_maps', it refuses in a silent way, being that the key was already inserted, however `add_decl_to_scope', `bind_function_type_life_time' successfully registered the ctf type object. In this patch `process_ctf_type' delegates register types task to `process_ctf_*' functions guaranteeing a single ctf type registration, also it improves the performance looking for the type before start to build it again. * src/abg-ctf-reader.cc (process_ctf_base_type): Add new `translation_unit_sptr' parameter. Add condition to validate success 'base_type' construction and register type object. (process_ctf_typedef): Add `lookup_type' to get a `type_base' object when this was previously created, if this is not the case, register ctf type. Add condition to validate success 'base_type' construction and register type object. (process_ctf_function_type): Likewise. (process_ctf_array_type): Likewise. (process_ctf_qualified_type): Likewise. (process_ctf_pointer_type): Likewise. (process_ctf_struct_type): Add `add_decl_to_scope'. (process_ctf_union_type): Likewise. (process_ctf_type): Add `lookup_type' to get a `type_base' object when this was previously created. Delegate register type object to `process_ctf_*'. * tests/data/Makefile.am: Add tests I/O and expected files. * tests/data/test-read-ctf/test-array-of-pointers.[co]: New testcase. * tests/data/test-read-ctf/test-list-struct.[co]: Likewise. * tests/data/test-read-ctf/test-callback.[co]: Likewise. * tests/data/test-read-ctf/test-callback2.[co]: Likewise. * tests/data/test-read-ctf/test-functions-declaration.[co]: Likewise. * tests/data/test-read-ctf/test-forward-type-decl.[co]: Likewise. * tests/data/test-read-ctf/test-array-of-pointers.abi: Expected test output. * tests/data/test-read-ctf/test-callback.abi: Likewise. * tests/data/test-read-ctf/test-callback2.abi: Likewise. * tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise. * tests/data/test-read-ctf/test-functions-declaration.abi: Likewise. * tests/data/test-read-ctf/test-list-struct.abi: Likewise. * tests/test-read-ctf.cc: Add testcases to CTF test harness. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
cc1f38ffed
commit
b1bbb67b2f
@ -15,6 +15,7 @@
|
||||
|
||||
#include <fcntl.h> /* For open(3) */
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "ctf-api.h"
|
||||
|
||||
@ -39,6 +40,7 @@ namespace abigail
|
||||
{
|
||||
namespace ctf_reader
|
||||
{
|
||||
using std::dynamic_pointer_cast;
|
||||
|
||||
class read_context
|
||||
{
|
||||
@ -157,6 +159,10 @@ process_ctf_typedef(read_context *ctxt,
|
||||
if (!utype)
|
||||
return result;
|
||||
|
||||
result = dynamic_pointer_cast<typedef_decl>(ctxt->lookup_type(ctf_type));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result.reset(new typedef_decl(typedef_name, utype, location(),
|
||||
typedef_name /* mangled_name */));
|
||||
|
||||
@ -171,6 +177,12 @@ process_ctf_typedef(read_context *ctxt,
|
||||
decl->set_naming_typedef(result);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
add_decl_to_scope(result, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -187,6 +199,7 @@ process_ctf_typedef(read_context *ctxt,
|
||||
static type_decl_sptr
|
||||
process_ctf_base_type(read_context *ctxt,
|
||||
corpus_sptr corp,
|
||||
translation_unit_sptr tunit,
|
||||
ctf_dict_t *ctf_dictionary,
|
||||
ctf_id_t ctf_type)
|
||||
{
|
||||
@ -226,6 +239,12 @@ process_ctf_base_type(read_context *ctxt,
|
||||
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
add_decl_to_scope(result, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -284,6 +303,9 @@ process_ctf_function_type(read_context *ctxt,
|
||||
function_parms.push_back(parm);
|
||||
}
|
||||
|
||||
result = dynamic_pointer_cast<function_type>(ctxt->lookup_type(ctf_type));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* Ok now the function type itself. */
|
||||
result.reset(new function_type(ret_type,
|
||||
@ -291,8 +313,15 @@ process_ctf_function_type(read_context *ctxt,
|
||||
tunit->get_address_size(),
|
||||
ctf_type_align(ctf_dictionary, ctf_type)));
|
||||
|
||||
tunit->bind_function_type_life_time(result);
|
||||
result->set_is_artificial(true);
|
||||
if (result)
|
||||
{
|
||||
tunit->bind_function_type_life_time(result);
|
||||
result->set_is_artificial(true);
|
||||
decl_base_sptr function_type_decl = get_type_declaration(result);
|
||||
add_decl_to_scope(function_type_decl, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -394,6 +423,7 @@ process_ctf_struct_type(read_context *ctxt,
|
||||
refer to this struct, we have to make it available in the cache
|
||||
at this point even if the members haven't been added to the IR
|
||||
node yet. */
|
||||
add_decl_to_scope(result, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
|
||||
/* Now add the struct members as specified in the CTF type description.
|
||||
@ -442,6 +472,7 @@ process_ctf_union_type(read_context *ctxt,
|
||||
refer to this union, we have to make it available in the cache
|
||||
at this point even if the members haven't been added to the IR
|
||||
node yet. */
|
||||
add_decl_to_scope(result, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
|
||||
/* Now add the union members as specified in the CTF type description.
|
||||
@ -498,6 +529,10 @@ process_ctf_array_type(read_context *ctxt,
|
||||
if (!index_type)
|
||||
return result;
|
||||
|
||||
result = dynamic_pointer_cast<array_type_def>(ctxt->lookup_type(ctf_type));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* The number of elements of the array determines the IR subranges
|
||||
type to build. */
|
||||
array_type_def::subranges_type subranges;
|
||||
@ -529,6 +564,13 @@ process_ctf_array_type(read_context *ctxt,
|
||||
|
||||
/* Finally build the IR for the array type and return it. */
|
||||
result.reset(new array_type_def(element_type, subranges, location()));
|
||||
if (result)
|
||||
{
|
||||
decl_base_sptr array_type_decl = get_type_declaration(result);
|
||||
add_decl_to_scope(array_type_decl, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -566,6 +608,14 @@ process_ctf_qualified_type(read_context *ctxt,
|
||||
ABG_ASSERT_NOT_REACHED;
|
||||
|
||||
result.reset(new qualified_type_def(utype, qualifiers, location()));
|
||||
|
||||
if (result)
|
||||
{
|
||||
decl_base_sptr qualified_type_decl = get_type_declaration(result);
|
||||
add_decl_to_scope(qualified_type_decl, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -597,10 +647,20 @@ process_ctf_pointer_type(read_context *ctxt,
|
||||
if (!target_type)
|
||||
return result;
|
||||
|
||||
result = dynamic_pointer_cast<pointer_type_def>(ctxt->lookup_type(ctf_type));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result.reset(new pointer_type_def(target_type,
|
||||
ctf_type_size(ctf_dictionary, ctf_type) * 8,
|
||||
ctf_type_align(ctf_dictionary, ctf_type) * 8,
|
||||
location()));
|
||||
if (result)
|
||||
{
|
||||
add_decl_to_scope(result, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -657,6 +717,12 @@ process_ctf_enum_type(read_context *ctxt,
|
||||
const char *enum_name = ctf_type_name_raw(ctf_dictionary, ctf_type);
|
||||
result.reset(new enum_type_decl(enum_name, location(),
|
||||
utype, enms, enum_name));
|
||||
if (result)
|
||||
{
|
||||
add_decl_to_scope(result, tunit->get_global_scope());
|
||||
ctxt->add_type(ctf_type, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -683,43 +749,31 @@ process_ctf_type(read_context *ctxt,
|
||||
int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
|
||||
type_base_sptr result;
|
||||
|
||||
if ((result = ctxt->lookup_type(ctf_type)))
|
||||
return result;
|
||||
|
||||
switch (type_kind)
|
||||
{
|
||||
case CTF_K_INTEGER:
|
||||
case CTF_K_FLOAT:
|
||||
{
|
||||
type_decl_sptr type_decl
|
||||
= process_ctf_base_type(ctxt, corp, ctf_dictionary, ctf_type);
|
||||
|
||||
if (type_decl)
|
||||
{
|
||||
add_decl_to_scope(type_decl, tunit->get_global_scope());
|
||||
result = is_type(type_decl);
|
||||
}
|
||||
= process_ctf_base_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
result = is_type(type_decl);
|
||||
break;
|
||||
}
|
||||
case CTF_K_TYPEDEF:
|
||||
{
|
||||
typedef_decl_sptr typedef_decl
|
||||
= process_ctf_typedef(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (typedef_decl)
|
||||
{
|
||||
add_decl_to_scope(typedef_decl, tunit->get_global_scope());
|
||||
result = is_type(typedef_decl);
|
||||
}
|
||||
result = is_type(typedef_decl);
|
||||
break;
|
||||
}
|
||||
case CTF_K_POINTER:
|
||||
{
|
||||
pointer_type_def_sptr pointer_type
|
||||
= process_ctf_pointer_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (pointer_type)
|
||||
{
|
||||
add_decl_to_scope(pointer_type, tunit->get_global_scope());
|
||||
result = pointer_type;
|
||||
}
|
||||
result = pointer_type;
|
||||
break;
|
||||
}
|
||||
case CTF_K_CONST:
|
||||
@ -728,79 +782,42 @@ process_ctf_type(read_context *ctxt,
|
||||
{
|
||||
type_base_sptr qualified_type
|
||||
= process_ctf_qualified_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (qualified_type)
|
||||
{
|
||||
decl_base_sptr qualified_type_decl = get_type_declaration(qualified_type);
|
||||
|
||||
add_decl_to_scope(qualified_type_decl, tunit->get_global_scope());
|
||||
result = qualified_type;
|
||||
}
|
||||
result = qualified_type;
|
||||
break;
|
||||
}
|
||||
case CTF_K_ARRAY:
|
||||
{
|
||||
array_type_def_sptr array_type
|
||||
= process_ctf_array_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (array_type)
|
||||
{
|
||||
decl_base_sptr array_type_decl = get_type_declaration(array_type);
|
||||
|
||||
add_decl_to_scope(array_type_decl, tunit->get_global_scope());
|
||||
result = array_type;
|
||||
}
|
||||
result = array_type;
|
||||
break;
|
||||
}
|
||||
case CTF_K_ENUM:
|
||||
{
|
||||
enum_type_decl_sptr enum_type
|
||||
= process_ctf_enum_type(ctxt, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (enum_type)
|
||||
{
|
||||
add_decl_to_scope(enum_type, tunit->get_global_scope());
|
||||
result = enum_type;
|
||||
}
|
||||
|
||||
result = enum_type;
|
||||
break;
|
||||
}
|
||||
case CTF_K_FUNCTION:
|
||||
{
|
||||
function_type_sptr function_type
|
||||
= process_ctf_function_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (function_type)
|
||||
{
|
||||
decl_base_sptr function_type_decl = get_type_declaration(function_type);
|
||||
|
||||
add_decl_to_scope(function_type_decl, tunit->get_global_scope());
|
||||
result = function_type;
|
||||
}
|
||||
result = function_type;
|
||||
break;
|
||||
}
|
||||
case CTF_K_STRUCT:
|
||||
{
|
||||
class_decl_sptr struct_decl
|
||||
= process_ctf_struct_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (struct_decl)
|
||||
{
|
||||
add_decl_to_scope(struct_decl, tunit->get_global_scope());
|
||||
result = is_type(struct_decl);
|
||||
}
|
||||
result = is_type(struct_decl);
|
||||
break;
|
||||
}
|
||||
case CTF_K_UNION:
|
||||
{
|
||||
union_decl_sptr union_decl
|
||||
= process_ctf_union_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
|
||||
|
||||
if (union_decl)
|
||||
{
|
||||
add_decl_to_scope(union_decl, tunit->get_global_scope());
|
||||
result = is_type(union_decl);
|
||||
}
|
||||
result = is_type(union_decl);
|
||||
break;
|
||||
}
|
||||
case CTF_K_UNKNOWN:
|
||||
@ -809,9 +826,7 @@ process_ctf_type(read_context *ctxt,
|
||||
break;
|
||||
}
|
||||
|
||||
if (result)
|
||||
ctxt->add_type(ctf_type, result);
|
||||
else
|
||||
if (!result)
|
||||
fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type);
|
||||
|
||||
return result;
|
||||
|
@ -648,6 +648,24 @@ test-read-ctf/test-struct-iteration.c \
|
||||
test-read-ctf/test-struct-iteration.o.abi \
|
||||
test-read-ctf/PR27700/test-PR27700.abi \
|
||||
test-read-ctf/PR26261/PR26261-exe.abi \
|
||||
test-read-ctf/test-callback.c \
|
||||
test-read-ctf/test-callback.abi \
|
||||
test-read-ctf/test-callback.o \
|
||||
test-read-ctf/test-array-of-pointers.c \
|
||||
test-read-ctf/test-array-of-pointers.o \
|
||||
test-read-ctf/test-array-of-pointers.abi \
|
||||
test-read-ctf/test-functions-declaration.abi \
|
||||
test-read-ctf/test-functions-declaration.c \
|
||||
test-read-ctf/test-functions-declaration.o \
|
||||
test-read-ctf/test-forward-type-decl.abi \
|
||||
test-read-ctf/test-forward-type-decl.o \
|
||||
test-read-ctf/test-forward-type-decl.c \
|
||||
test-read-ctf/test-list-struct.c \
|
||||
test-read-ctf/test-list-struct.o \
|
||||
test-read-ctf/test-list-struct.abi \
|
||||
test-read-ctf/test-callback2.c \
|
||||
test-read-ctf/test-callback2.o \
|
||||
test-read-ctf/test-callback2.abi \
|
||||
\
|
||||
test-annotate/test0.abi \
|
||||
test-annotate/test1.abi \
|
||||
|
36
tests/data/test-read-ctf/test-array-of-pointers.abi
Normal file
36
tests/data/test-read-ctf/test-array-of-pointers.abi
Normal file
@ -0,0 +1,36 @@
|
||||
<abi-corpus version='2.1' path='data/test-read-ctf/test-array-of-pointers.o'>
|
||||
<elf-variable-symbols>
|
||||
<elf-symbol name='t' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-variable-symbols>
|
||||
<abi-instr address-size='64' language='LANG_C'>
|
||||
<class-decl name='cgroup' size-in-bits='256' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='s1' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='css_set' size-in-bits='256' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-3'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='s0' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='state' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-4'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='cg' type-id='type-id-5' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='task' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-6'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='s' type-id='type-id-7' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<array-type-def dimensions='1' type-id='type-id-8' size-in-bits='256' alignment-in-bits='64' id='type-id-2'>
|
||||
<subrange length='4' type-id='type-id-9' id='type-id-10'/>
|
||||
</array-type-def>
|
||||
<type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-9'/>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
|
||||
<pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
|
||||
<pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/>
|
||||
<pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-11'/>
|
||||
<var-decl name='t' type-id='type-id-11' mangled-name='t' visibility='default'/>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
20
tests/data/test-read-ctf/test-array-of-pointers.c
Normal file
20
tests/data/test-read-ctf/test-array-of-pointers.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Test a array of pointer definition as struct member
|
||||
* gcc -gctf -c test-array-of-pointers.c -o test-array-of-pointer.o
|
||||
*/
|
||||
struct task {
|
||||
struct css_set *s;
|
||||
};
|
||||
|
||||
struct state {
|
||||
struct cgroup *cg;
|
||||
};
|
||||
|
||||
struct css_set {
|
||||
struct state *s0[4];
|
||||
};
|
||||
|
||||
struct cgroup {
|
||||
struct state *s1[4];
|
||||
};
|
||||
|
||||
struct task *t;
|
BIN
tests/data/test-read-ctf/test-array-of-pointers.o
Normal file
BIN
tests/data/test-read-ctf/test-array-of-pointers.o
Normal file
Binary file not shown.
31
tests/data/test-read-ctf/test-callback.abi
Normal file
31
tests/data/test-read-ctf/test-callback.abi
Normal file
@ -0,0 +1,31 @@
|
||||
<abi-corpus version='2.1' path='data/test-read-ctf/test-callback.o'>
|
||||
<elf-function-symbols>
|
||||
<elf-symbol name='assign' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='f2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-function-symbols>
|
||||
<abi-instr address-size='64' language='LANG_C'>
|
||||
<class-decl name='test' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='fn1' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
|
||||
<type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
|
||||
<pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
|
||||
<function-decl name='assign' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'>
|
||||
<return type-id='type-id-7'/>
|
||||
</function-decl>
|
||||
<function-decl name='f2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'>
|
||||
<parameter type-id='type-id-3'/>
|
||||
<parameter type-id='type-id-4'/>
|
||||
<return type-id='type-id-7'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' alignment-in-bits='8' id='type-id-6'>
|
||||
<parameter type-id='type-id-3'/>
|
||||
<parameter type-id='type-id-4'/>
|
||||
<return type-id='type-id-7'/>
|
||||
</function-type>
|
||||
<type-decl name='void' id='type-id-7'/>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
16
tests/data/test-read-ctf/test-callback.c
Normal file
16
tests/data/test-read-ctf/test-callback.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* Test a simple callback as a struct member
|
||||
* gcc -gctf -c test-callback.c -o test-callback.o
|
||||
*/
|
||||
struct test {
|
||||
void (*fn1)(int, long);
|
||||
};
|
||||
|
||||
void f2(int a, long b)
|
||||
{
|
||||
}
|
||||
|
||||
void assign()
|
||||
{
|
||||
struct test *tt;
|
||||
tt->fn1 = f2;
|
||||
}
|
BIN
tests/data/test-read-ctf/test-callback.o
Normal file
BIN
tests/data/test-read-ctf/test-callback.o
Normal file
Binary file not shown.
20
tests/data/test-read-ctf/test-callback2.abi
Normal file
20
tests/data/test-read-ctf/test-callback2.abi
Normal file
@ -0,0 +1,20 @@
|
||||
<abi-corpus version='2.1' path='data/test-read-ctf/test-callback2.o'>
|
||||
<elf-variable-symbols>
|
||||
<elf-symbol name='s0' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-variable-symbols>
|
||||
<abi-instr address-size='64' language='LANG_C'>
|
||||
<class-decl name='s0' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mem_fun' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
|
||||
<pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
|
||||
<var-decl name='s0' type-id='type-id-5' mangled-name='s0' visibility='default'/>
|
||||
<function-type size-in-bits='64' alignment-in-bits='8' id='type-id-4'>
|
||||
<parameter type-id='type-id-5'/>
|
||||
<return type-id='type-id-3'/>
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
11
tests/data/test-read-ctf/test-callback2.c
Normal file
11
tests/data/test-read-ctf/test-callback2.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* Test a simple callback as a struct member
|
||||
* that takes a pointer to a struct parent as
|
||||
* argument
|
||||
* gcc -gctf -c test-callback2.c -o test-callback2.o
|
||||
*/
|
||||
struct s0
|
||||
{
|
||||
int (*mem_fun)(struct s0 *);
|
||||
};
|
||||
|
||||
struct s0 *s0;
|
BIN
tests/data/test-read-ctf/test-callback2.o
Normal file
BIN
tests/data/test-read-ctf/test-callback2.o
Normal file
Binary file not shown.
29
tests/data/test-read-ctf/test-forward-type-decl.abi
Normal file
29
tests/data/test-read-ctf/test-forward-type-decl.abi
Normal file
@ -0,0 +1,29 @@
|
||||
<abi-corpus version='2.1' path='data/test-read-ctf/test-forward-type-decl.o'>
|
||||
<elf-variable-symbols>
|
||||
<elf-symbol name='addr' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-variable-symbols>
|
||||
<abi-instr address-size='64' language='LANG_C'>
|
||||
<class-decl name='address_space' size-in-bits='128' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='rb_root' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='page' type-id='type-id-3' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='page' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-4'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mapping' type-id='type-id-5' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='rb_node' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-6'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='rb_left' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
|
||||
<pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>
|
||||
<pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
|
||||
<var-decl name='addr' type-id='type-id-5' mangled-name='addr' visibility='default'/>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
23
tests/data/test-read-ctf/test-forward-type-decl.c
Normal file
23
tests/data/test-read-ctf/test-forward-type-decl.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* Test a forward type declaration as a struct member
|
||||
* to exercise circular dependencies.
|
||||
* gcc -gctf -c test-forward-type-decl.c -o \
|
||||
* test-forward-type-decl.o
|
||||
*/
|
||||
typedef struct page *page_t;
|
||||
|
||||
struct rb_node {
|
||||
struct rb_node *rb_left;
|
||||
};
|
||||
|
||||
struct address_space;
|
||||
|
||||
struct page {
|
||||
struct address_space *mapping;
|
||||
};
|
||||
|
||||
struct address_space {
|
||||
struct rb_node *rb_root;
|
||||
struct page *page;
|
||||
};
|
||||
|
||||
struct address_space *addr;
|
BIN
tests/data/test-read-ctf/test-forward-type-decl.o
Normal file
BIN
tests/data/test-read-ctf/test-forward-type-decl.o
Normal file
Binary file not shown.
25
tests/data/test-read-ctf/test-functions-declaration.abi
Normal file
25
tests/data/test-read-ctf/test-functions-declaration.abi
Normal file
@ -0,0 +1,25 @@
|
||||
<abi-corpus version='2.1' path='data/test-read-ctf/test-functions-declaration.o'>
|
||||
<elf-function-symbols>
|
||||
<elf-symbol name='attribute_container_add_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='attribute_container_device_trigger' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-function-symbols>
|
||||
<abi-instr address-size='64' language='LANG_C'>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
|
||||
<type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
|
||||
<pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
|
||||
<function-decl name='attribute_container_add_device' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'>
|
||||
<parameter type-id='type-id-4'/>
|
||||
<return type-id='type-id-5'/>
|
||||
</function-decl>
|
||||
<function-decl name='attribute_container_device_trigger' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'>
|
||||
<parameter type-id='type-id-4'/>
|
||||
<return type-id='type-id-5'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' alignment-in-bits='8' id='type-id-3'>
|
||||
<parameter type-id='type-id-1'/>
|
||||
<parameter type-id='type-id-2'/>
|
||||
<return type-id='type-id-5'/>
|
||||
</function-type>
|
||||
<type-decl name='void' id='type-id-5'/>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
16
tests/data/test-read-ctf/test-functions-declaration.c
Normal file
16
tests/data/test-read-ctf/test-functions-declaration.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* Test declaring twice a function pinter a struct member
|
||||
* gcc -gctf -c test-functions-declaration.c -o \
|
||||
* test-functions-declaration.o
|
||||
*/
|
||||
void
|
||||
attribute_container_add_device(
|
||||
void (*fn1)(int, long))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
attribute_container_device_trigger(
|
||||
void (*fn2)(int , long))
|
||||
{
|
||||
|
||||
}
|
BIN
tests/data/test-read-ctf/test-functions-declaration.o
Normal file
BIN
tests/data/test-read-ctf/test-functions-declaration.o
Normal file
Binary file not shown.
20
tests/data/test-read-ctf/test-list-struct.abi
Normal file
20
tests/data/test-read-ctf/test-list-struct.abi
Normal file
@ -0,0 +1,20 @@
|
||||
<abi-corpus version='2.1' path='data/test-read-ctf/test-list-struct.o'>
|
||||
<elf-variable-symbols>
|
||||
<elf-symbol name='n1' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='n2' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-variable-symbols>
|
||||
<abi-instr address-size='64' language='LANG_C'>
|
||||
<class-decl name='rb_node_b' size-in-bits='128' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='this' type-id='type-id-2' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='a' type-id='type-id-3' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
|
||||
<var-decl name='n1' type-id='type-id-1' mangled-name='n1' visibility='default'/>
|
||||
<var-decl name='n2' type-id='type-id-1' mangled-name='n2' visibility='default'/>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
11
tests/data/test-read-ctf/test-list-struct.c
Normal file
11
tests/data/test-read-ctf/test-list-struct.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* Test a ADT where a struct member is a pointer to
|
||||
* itself.
|
||||
* gcc -gctf -c test-callback.c -o test-callback.o
|
||||
*/
|
||||
|
||||
struct rb_node_b {
|
||||
struct rb_node_b *this;
|
||||
int a;
|
||||
};
|
||||
|
||||
struct rb_node_b n1, n2;
|
BIN
tests/data/test-read-ctf/test-list-struct.o
Normal file
BIN
tests/data/test-read-ctf/test-list-struct.o
Normal file
Binary file not shown.
@ -220,6 +220,54 @@ static InOutSpec in_out_specs[] =
|
||||
"data/test-read-ctf/PR27700/test-PR27700.abi",
|
||||
"output/test-read-ctf/PR27700/test-PR27700.abi",
|
||||
},
|
||||
{
|
||||
"data/test-read-ctf/test-callback.o",
|
||||
"",
|
||||
"",
|
||||
SEQUENCE_TYPE_ID_STYLE,
|
||||
"data/test-read-ctf/test-callback.abi",
|
||||
"output/test-read-ctf/test-callback.abi",
|
||||
},
|
||||
{
|
||||
"data/test-read-ctf/test-array-of-pointers.o",
|
||||
"",
|
||||
"",
|
||||
SEQUENCE_TYPE_ID_STYLE,
|
||||
"data/test-read-ctf/test-array-of-pointers.abi",
|
||||
"output/test-read-ctf/test-array-of-pointers.abi",
|
||||
},
|
||||
{
|
||||
"data/test-read-ctf/test-functions-declaration.o",
|
||||
"",
|
||||
"",
|
||||
SEQUENCE_TYPE_ID_STYLE,
|
||||
"data/test-read-ctf/test-functions-declaration.abi",
|
||||
"output/test-read-ctf/test-functions-declaration.abi",
|
||||
},
|
||||
{
|
||||
"data/test-read-ctf/test-forward-type-decl.o",
|
||||
"",
|
||||
"",
|
||||
SEQUENCE_TYPE_ID_STYLE,
|
||||
"data/test-read-ctf/test-forward-type-decl.abi",
|
||||
"output/test-read-ctf/test-forward-type-decl.abi",
|
||||
},
|
||||
{
|
||||
"data/test-read-ctf/test-list-struct.o",
|
||||
"",
|
||||
"",
|
||||
SEQUENCE_TYPE_ID_STYLE,
|
||||
"data/test-read-ctf/test-list-struct.abi",
|
||||
"output/test-read-ctf/test-list-struct.abi",
|
||||
},
|
||||
{
|
||||
"data/test-read-ctf/test-callback2.o",
|
||||
"",
|
||||
"",
|
||||
SEQUENCE_TYPE_ID_STYLE,
|
||||
"data/test-read-ctf/test-callback2.abi",
|
||||
"output/test-read-ctf/test-callback2.abi",
|
||||
},
|
||||
// This should be the last entry.
|
||||
{NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user