@@ -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 \
new file mode 100644
@@ -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>
new file mode 100644
@@ -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;
new file mode 100644
GIT binary patch
literal 1464
zcmbtUO>fgc5S@fjphyu#98lq4PP77lBuEJLfGkx|gb+852(6uMYBjMV??y^a{0D^i
zJsdgn2lx$e;)3A4*iNi%dg4iMcjnEEcV}Yf<BK;hyPb|S=*V-~c#SIZySuUDl^M%T
z*_B^Edh5v1CPjL%$?G+5VgCkx0e8V?HEHuaaG$wPLE;9u15)>}KLLqrU>|JqBZ>fP
z?|@CdPZ3~#js6uF_bO+H`Eg})z0Kt+$TNBG8vVAtZWLF*IU-h>b4iW)V6+uumDQ4t
z%VIv0Ns*7ed2X_Cu18*$BRoJ%Oe99EglEN6hsiQohDE8;i4IMfhLbE&Nj6s5#GlWM
zEw!44RvT-=k+N!K`VdEcYELUqm8Dwx#i>6laE2~TkcylfA0K%KCvV>!dV^sQ1(7$5
zhJyj<9q7eOm)TV3R!t7s0{ino_Kp(iO6O~<XUwzmSN$UAGBDngpMTx>K7>8t<STIQ
zE3h$t+x@LbV3t#>6706D_Or&adSNBtJS0erkpQ#6QcT&C1bJa~fIfWu8tHlMkMnsj
zD+_dPm(B72yYoF_&wO9nh}%xfcIWp1F>0I1RLOC*U0B`vhsfY8FRNeAxqg!CKZfo;
zlc_Nm;FA+{Tp1vTTJ!y}hWK75KC0aH+SE5Y|0^1Modo00HgQYtYiRtoTi+zSjo{wP
z?Vrb7sD&2Q;wwH2;QtV%rv5HPfVw+->WjMmKAjfaw)PO)R{y!Kf8VO5>DK=P9Oi#k
literal 0
HcmV?d00001
new file mode 100644
@@ -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>
new file mode 100644
@@ -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;
+}
new file mode 100644
GIT binary patch
literal 1856
zcmbtUPixdr5TCTQt=O(>5vkTgK#&&QWOol9M0BOpuHYXO3SPt}+w5*Io7Ci0b_MY!
z6fgY{egVHh!Gm8yuov&@$%CNtOWx3D$Vmt0&CGB9z4zuNZ#M4TnX)VrvgjrqTY?fD
zP9N)?T<uVe7HO-y|8@WMukQZdw}Yo2VRhea{Oo?pLm2t-WoAk;FN>n(JWFt0^Lv&P
z<~in*%omw2F=Ic>7ZAJ544Tz^EQ)P&vvX)T!+e7I6f@H-Y@5rRhQ&5&b&ArkYd9YI
zG3EJ%N;UMx9?Eq|1(~9kNw`B{tSCz2feob}x5&$~a1c|!P3|xm1+G8wCvK8@y(n<A
zwC6^l@A=`t3!}!~Zl=<}8@VW#xjUZna<#$WPNS##h1K(-$oG2BogUHV`ucTyb@Rd2
zn%!zUO{ZzMo9$MM*<KCCyFnU`f>?RcT7Cq5?))w|htFXh0u!>djdOy|7J{r-kI5R>
zt(Aqj`2%+1ZuI@|+?j6I>Tjpk7iaHsfcD)0&a{L@{Pzn#pejP&8T$Ua$~Rq%^e@*L
zww4S$-wR{dH*m4@Js=Yo+c55rr=sTrFP+cV;+^0P2-#Y}TLKGpv?93lBPW}Tl;^Wl
zX(5NAr9tF5Di|wrFko{0EF*`9%S$rCw8)7Q6*xSgMy7bq+8)Gv&Tg9UOx1*(yi72B
z)=#}rAp7}WX>$S00N;~I9c|bq$hy1}fmc|;d+G=vQeUQgulNp;i?;$29RCF1=H0`;
zjirLh{jYKiYW{0}i*w60(RLdP)1#8JWYRT`0oFvYK_7JB6$67R`66!_m>K$60!*+X
z_90{VUz%?eDMvcLyf3+b#DE6O2rcK=HSh#M29@)D_EpV)Sr0_|WB&N3OTNs%syEsV
pb^kF8rUhn{Ea#(UdG-v^k<Q2aG^u>8_@7kecQyFJOlG~D{|9qBlT!cy
literal 0
HcmV?d00001
new file mode 100644
@@ -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>
new file mode 100644
@@ -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;
new file mode 100644
GIT binary patch
literal 1312
zcmbtTOK;Oa5FUq6UQ*SEKnO18)K;z6Nsc`fOA!Pi#Em1OYiFCf_z`(GQgh<3^r!Go
zxb|A^2xjcr*x8m-M;gz}H{Z<e%*sFBeR|*XJh0-y3AB+#0Zx0ZAJuLI&)_Ni{?%V)
zc3TSc(I<V(x`lR%IzuI#Vp8(yJk(c~iy=Hjr5wrzS-+tX?*$#mIrM7Tq#i7r56IC2
zNDBkG%D<g03JSyXGFM@|jF(|q$s|*uu97fIV;QG2nP$Oau1%$69vY>M4yV${+6@q#
z28lUqqC{p{ER*jekpN7_<70n+^7+ewKOBjH82F>XXgEam_toWGRcWpYBeMg(9M4kE
zhgHx6?`L-wkK@ifT)A#2--nyO>nOku0^3k;pia?FYoVEf?$vQ4AoMafGDd5v#-3Zx
zs7nKab^s#Q8U)UdpE9R;Koq4>0tX1R!BucPD;8p2l{mFo+H>z|Ut>MZy5aPRoY;o$
z-rit>uy!L2GiuDOuUo%|4BFxU>R0>aPHudJxZ9Jc5q(hH2XwhZ<Pe6BwI*+wc({hP
zXW2f-n74kHdT|$c2lpdlk5E@XIX9Vey?ZZrexkXx)Z&WkKXAV%%(L|`JGi@hN?mjP
abLLsYunqBFxczpN{KLerD`w-k_5T2Ot7wz}
literal 0
HcmV?d00001
new file mode 100644
@@ -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>
new file mode 100644
@@ -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;
new file mode 100644
GIT binary patch
literal 1408
zcmbtT&2G~`5T2CqFGW=90R<$CghVUwI?0V5DoYg<A;b-CC|cW_)WUz--HQ6el_%i9
z)07);!85?Aw=%Qdt*vc1G19m5v)?!IjN>ma-@e)!jlkIm4xrCm72s^Ek7E<Ya2M{t
zpI_t4n}ePLV~h#6EbgKIiujJWfp}p-G5sE5O58bujOqkzJ|*oF1R3>wj))Q05jzN{
zeTXp`ajZ?Qxd>n~m}_Dly5Va9Jj<j|YN;BY3XsXNsx#vYvC@>wy4GN*C2yL%S{n&O
z$8{;9q)pnWmOL#)q+}WudBT%?&GRBWX_S_Nmys4qt0?1|n=r&;7N&aDWvg0#<}wR)
z+lVj|X~9x}qr=1fVE5?V`@LYkU^6xg7PG~CjtF+eX(MD_ic0fh&y7bj2MF2;%5ZO^
zv%wy4M_oSH0Wz-|-H+k-g?}@}!Z!5Vq<3YEh6^{%KzjvXsx387&}-TGV;5<0s)5m3
zfF()+!<FDsmoyr%s@8(xD526k{bciXb;251;{tT+p5VXy160$@^j{lVJWK|$zrV+L
zN40)49XamYmDAThMF#EiU;4{E+fIH?--6$hs4*RAAG}L1HQyW6W`^A#-z@Q2Uow%?
zJHL-r7Z0gFHWfE;-(c+~!hDZ|20yLde=dK1qWM~Cb8hvoZO_}5=k)gnb$|DC72Bqd
WEYCTAtZls5q+eS7M<=x2*Z&2rIf66*
literal 0
HcmV?d00001
new file mode 100644
@@ -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>
new file mode 100644
@@ -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))
+{
+
+}
new file mode 100644
GIT binary patch
literal 1848
zcmbtUL2J}d5T3NPt=dWzDMCf!$rjDaZVw)c%1W^<A|8ZFFJ*m6Ubn$)Qj@o3R}ei(
zd+VR^E_m=~c=89>)82Guci#5-x+3VnyqWoCzBkExle~ZOY-7Unz=#Kr;4CsIK!5Vg
zZw%Z9%)=aPZykT%I)2wb+5KX<r{AU~O#QZT*v_IQU0^*z`w5i@GpN(3_fh#NC?xU7
zL2Qw515yHc18fTY3#cmuVhP1QQUZ!Frk;(_ws3`Bi2MA$=V6g1Ahj;jsH0UgE^;l?
zT$Rm49j38rVxrYjC8W8AtjJqFIpgYOk}wCt{i3bHs2BCZqLgu_!m5nJERAH8wq%+G
zor6l3O149-DqV$%)N<ek2qr<S_lD74Cy#Yn<W-QUIFqHMK*Ru>>+5U&^5*mH6~DeJ
zYNF<^)>i9vRDW4@4^)}96~0HtrvrRCgA+p*o}%}eFe4tvd<$@$6W-ew;B^<grMa2e
z6HMMjoRs7;Esw7(e4JRHpWeU%3@P`3aFlWRVdnfweW&2Z&+{38Ni!Q(@)r8nEPT)l
zv4@PC*jS)*4*qnUf4R+ZX=gZm>`OvZO=_gUj=@LIBdT6o%LoL{!O-p-Pphs5K_dYo
zswxmT4!9I;x>68%p_RZp3@R<-*BrO<jyNa_ym;LMQL0P|wcp$;Wm}m?`7gVKY`P=+
zOQa1Ow4f{w&1f}qWPsb~5N7>W2C0{(z_Bj>4(4gT{*`|Zx$d6S()54hB%KiI%&!s2
zlCNBN*TTp(d}G%v%q~4O1vWUQ_9<fYx3p)AD1GL;&qZftON0THy8LAZcI;yGUH&d&
z^uK7J+OoqJV)|dgBykP@1{aU(O{ovuzsq&>ebAOJ|03gDHZpzYzZxM!$351o2)naG
Ol}8L_L)vI{`M&^>zQy(c
literal 0
HcmV?d00001
new file mode 100644
@@ -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>
new file mode 100644
@@ -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;
new file mode 100644
GIT binary patch
literal 1344
zcmb7D%We}f6unbIC{#jJLOcqKfeo!-Jee%JKqFPO5<=`)qSiAp&4_uVV@FC>@Hu=2
zf5JDw55PT%-567lxYDujJ@*{PzM6b`_2zghipWJoFKJUbmgw`=CeK%CPCImqeta8T
zb{=mew9Pqi$0FwajL|c2KJbun&%)KN$A|90yTd@>NA5Cm#x;hG+t5SDF&yv`<LJIP
zZM%s&EyzqOO;u}1QkzjbrgYjhDlL}9GVOX<)+*I~nbuVyi|Slfbuyo6(<|AeMrotd
zi8OMRCQMF}(tKD~b)`+h%6Vx-Npx~_bQtfSynS~NXJauEqj)?TXBi{jSBshIt46g(
z)(5yK!rqmxbIvw?U-T86i^$e^-@gL=0e$}&YA~x^Z&G$fbl>u>c01v@$?vaPPmF|K
zHbxe_n|{4dU1rq6kid*c6k3zu`S8*;crA&xGfMF5cu=zZXzTNKE@pklGcn8X*8g8W
zVhd(446J!jyE2^T6K;U>zNwWoU#)*Gq5m06@SXq79|uQV&fD@Ycn{A+E62hy44Oen
z8Ee3eAok+e3ZHu%Qs;O3p~v~s3n%c&E3~hfyTQQ!(~pJqhxfv){D3U<qW{JE&ropO
lWI*Tq4?uE&4`&a4+a9`y!i(@(yWG3V|J3^5dtRiW{}<)|Z6W{w
literal 0
HcmV?d00001
@@ -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}
};