Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yet another missadventure with nodes in TNF_RSAFE/ types forward declaration mecanismes #332

Open
ptizoom opened this issue Apr 25, 2019 · 8 comments

Comments

@ptizoom
Copy link

ptizoom commented Apr 25, 2019

in the bigger of schemes I am trying to compile this asn1c for LTE-S1AP-r14 messaging interface (I have attached the fellow FYI s1ap-14.5.0.asn1.zip
), and I think a similar issue operates there with this smaller example I prepared to illustrate a problem:

example :
731-modules-circular-OK.asn1.zip

with commands:
pushd /usr/src/ep_asn1c-build/tests/tests-asn1c-compiler
../../asn1c/asn1c -S /usr/src/asn1c/skeletons -Pfcompound-names /usr/src/asn1c/tests/tests-asn1c-compiler/731-modules-circular-OK.asn1 -pdu=all -fcompound-names -gen-PER

would give...:

/*** <<< INCLUDES [S1-A] >>> ***/
#include "S2-A.h"
...
/*** <<< TYPE-DECLS [S1-A] >>> ***/
typedef struct S1_A {
...
        S2_A_t   b;
...
} S1_A_t;
/*** <<< FUNC-DECLS [S1-A] >>> ***/
...


/*** <<< INCLUDES [S2-A] >>> ***/
#include "S4-Buck.h"
...
/*** <<< TYPE-DECLS [S2-A] >>> ***/
typedef struct S2_A {
        S4_Buck_78P0_t   a2;
        S4_Buck_78P1_t   a6;
 ...
} S2_A_t;

/*** <<< FUNC-DECLS [S2-A] >>> ***/
...

/*** <<< INCLUDES [S4-Buck] >>> ***/
...
/*** <<< FWD-DECLS [S4-Buck] >>> ***/
struct S1_A_x;
struct S6_B;

/*** <<< TYPE-DECLS [S4-Buck] >>> ***/
typedef struct S4_Buck_78P0 {
        A_SEQUENCE_OF(struct S1_A_x) list;
	...
} S4_Buck_78P0_t;
typedef struct S4_Buck_78P1 {
        A_SEQUENCE_OF(struct S6_B) list;
	...
} S4_Buck_78P1_t;
...
/*** <<< POST-INCLUDE [S4-Buck] >>> ***/
#include "S5-Field.h"
...


/*** <<< INCLUDES [S5-Field] >>> ***/
...
#include "S1-A.h"
#include "S2-A.h"

/*** <<< DEPS [S5-Field] >>> ***/

typedef enum S1_A_x__value_PR {
        S1_A_x__value_PR_NOTHING        /* No components present */

} S1_A_x__value_PR;
typedef enum S6_B__value_PR {
        S6_B__value_PR_NOTHING, /* No components present */
        S6_B__value_PR_S1_A,
        S6_B__value_PR_S2_A
} S6_B__value_PR;
...
/*** <<< FWD-DECLS [S5-Field] >>> ***/
struct S1_A;
struct S2_A;

/*** <<< TYPE-DECLS [S5-Field] >>> ***/
typedef struct S1_A_x {
...
        struct S1_A_x__value {
                S1_A_x__value_PR present;
                union S1_A_x__value_u {
                } choice;
		...
        } value;
	...
} S1_A_x_t;
typedef struct S6_B {
        long     id;
        struct S6_B__value {
                S6_B__value_PR present;
                union S6_B__value_u {
                        struct S1_A     *S1_A;
                        struct S2_A     *S2_A;
                } choice;
                /* Context for parsing across buffer boundaries */
                asn_struct_ctx_t _asn_ctx;
        } value;
...
/*** <<< POST-INCLUDE [S5-Field] >>> ***/
#include "S1-A.h"
#include "S2-A.h"
...

there,

  • including first
  • [S2-A]
  • [S4-Buck] is pre-included
  • in which structures S1_A_x and S6_B are declared forward.
    (and it is fine),
  • [S5-Field] is post included
    the structure is weird here as [S1-A] and [S2-A] are both forward declared and pre-included.
    so...
  •  [S1-A] is then pre-included.
    
  •    [S2-A] is pre-included
    

horror! we see that we started by S2-A, then we return without defining the S2_A_t type, needed to close [S1-A] S1_A_t type.

the problem is complex.
we would compile fine if starting by including [S1-A] first.
but each header needs to be compiled first to work.
so to fix this, I thought ...

  • a) we could forward declare S2_A in [S1-A], since already done that way in [S5-Field]
    and/or
  • b) disable the pre-includes of [S1-A] (and [S2-A]) in [S5-Field].

how best can this be done? can anyone suggest a general fix for this TNF_RSAFE ?

ta.

@velichkov
Copy link
Contributor

Hi @ptizoom,

yet another missadventure with nodes in TNF_RSAFE

Why yet another, which was the previous one?

../../asn1c/asn1c -S /usr/src/asn1c/skeletons -Pfcompound-names /usr/src/asn1c/tests/tests-asn1c-compiler/731-modules-circular-OK.asn1 -pdu=all -fcompound-names -gen-PER

Which asn1c version do you use?
Have you tried without -P?

For me it's working with the latest master 88ed3b5

$ sha256sum ./731-modules-circular-OK.asn1
2d1cfe814299188e6f4db3b0e6fc59aa3485b094dd63e6789f21b311b8d6d56b  ./731-modules-circular-OK.asn1

$ ../asn1c/asn1c -S ../skeletons -fcompound-names -pdu=all -fcompound-names -gen-PER ./731-modules-circular-OK.asn1

$ make -f converter-example.mk

$ ./converter-example -p list
Available PDU types:
S1-A
S2-A

Current master does not support APER encoding. You could use the vlm_master branch from mouse07410's fork

See also #185 and https://github.com/nextepc/nextepc/tree/7a8e32f4538407384b073d26b7cb62f6f6506431/lib/s1ap/support

@ptizoom
Copy link
Author

ptizoom commented Apr 28, 2019

  • the

'-P'

should have just a formatting effect!

  • and actually, after another thought, the include of [S1-A] even in the POST-INCLUDE [S5-Field] is doomed and will not work when [S2-A] is included first. so we need to forward declare S2-A in [S1-A] by default , to resolve this problem.

  • will try this vlm_master and aligne my APER version to it!

  • 'yet another' is a figure of speech! I believe hard graph had been injected into the code to sort out this forward declarations mecanisme

  • on the positive, it seems that forward declaration in inter module criss-cross of simple structures is working.
    but when objects and class are put into the pictures it gets mangled. I am only speculating here.

PS: can you show your [S5-Field] and [S1-A] headers?

@ptizoom
Copy link
Author

ptizoom commented May 4, 2019

well after tracing a bit, I realize [S2-A] is not yet completely compiled when asn1s_compile_expr() [S1-A], then does not detect the link within [S5-Field] (which calls [S1-A]).
In the end the algorithm detects the EM_UNRECURSE for [S2-A] and [S1-A], but too late, since S1-A is already output. we might need to create a dirty bit and the recompile the output a second time?

@brchiu
Copy link
Contributor

brchiu commented May 4, 2019

@ptizoom, if the problem you mentioned is cyclic inclusion of header file, then adding -findirect-choice when you generate the code can solve it. The price to pay is application developer need write more cumbersome code to handle CHOICE type.

There might be some sort of better solution, e.g. analyzing the dependency between each type, constant , .... , then constructing a DAG (directed acyclic graph) based on these dependency information and output an all-in-one header file which contains all generated C type with proper order.

I have spent some time trying this approach but without success.

Perhaps someone in the community could head to this direction.

@ptizoom
Copy link
Author

ptizoom commented May 4, 2019

yes, this is a cyclic graph issue, but because the asn1c_expr_t are not complete and yet we print out the compiled section on the fly. it will not work for all cases. usually compilers uses 2 passes!

and indeed I am using https://github.com/mouse07410/asn1c/ of "Chiu" and "mouse008".

@ptizoom
Copy link
Author

ptizoom commented May 12, 2019

what I found so far, on this self inflected muddle, is that during phase_1_1, the "S4-Buck" expression is instancied more than once., so one is chained:

  • "S1-A-X".next.tq_next."S2-A".menbers.tq_head."a2".reference.ref_expr."S4-Buck"

an the other...

  • "S1-A-X".reference.ref_expr."S3-C".next.tq_next."S4-Buck"

this is confusing the recurrences check up at the end..

the later "S4-Buck"(AMT-TYPE) issued from "S3-C"(AMT_OBJECTCLASS) is far more furnished and link to "S5-Field" (and linking back to "S1-A"); this is what we expect, whereas the earlier "S4-Buck" expression is a dead end !

in fact, ..."a2".reference.ref_expr is cloned systematically from "S4-Buck" (at
asn1f_fix_dereference_types (), ... asn1f_parameterization_fork())
and the loop link is lost through that clone.

@ptizoom
Copy link
Author

ptizoom commented May 22, 2019

and after a long effort, I think now , that the compiling of asn1_compile() resolves the "Component Relation Constraint: " but too late:

in this exemple ... recurrence with S1-A, S2-A is found when compiling S6-B, but S1-A has already been written out,

  • could they be in a phase_1+ instead ?

  • anyway I think to manage this issue expressions need to be backward linked too, and also cloned expressions need to be grouped under the same hash-key ?

  • or a second pass with asn1_compile() could be simplier done ?

@ptizoom
Copy link
Author

ptizoom commented May 24, 2019

I left a patch on mouse07410#53 which does the trick at least on S1-A.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants