Add the functions cil_write_parse_ast(), cil_write_build_ast(), and cil_write_resolve_ast() that can be used outside of libsepol. These functions take a FILE pointer and CIL db, do the CIL build through the desired phase, and then call cil_write_ast() to write the CIL AST at that point. Signed-off-by: James Carter <jwcart2@xxxxxxxxx> --- libsepol/cil/include/cil/cil.h | 3 ++ libsepol/cil/src/cil.c | 92 ++++++++++++++++++++++++++++++++++ libsepol/src/libsepol.map.in | 3 ++ 3 files changed, 98 insertions(+) diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h index e6f4503e..92fac6e1 100644 --- a/libsepol/cil/include/cil/cil.h +++ b/libsepol/cil/include/cil/cil.h @@ -60,6 +60,9 @@ extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_s extern void cil_set_target_platform(cil_db_t *db, int target_platform); extern void cil_set_policy_version(cil_db_t *db, int policy_version); extern void cil_write_policy_conf(FILE *out, struct cil_db *db); +extern int cil_write_parse_ast(FILE *out, cil_db_t *db); +extern int cil_write_build_ast(FILE *out, cil_db_t *db); +extern int cil_write_resolve_ast(FILE *out, cil_db_t *db); enum cil_log_level { CIL_ERR = 1, diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c index 99c8e288..1696ba82 100644 --- a/libsepol/cil/src/cil.c +++ b/libsepol/cil/src/cil.c @@ -50,6 +50,7 @@ #include "cil_binary.h" #include "cil_policy.h" #include "cil_strpool.h" +#include "cil_write_ast.h" int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = { {64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, @@ -572,6 +573,97 @@ exit: return rc; } +int cil_write_parse_ast(FILE *out, cil_db_t *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Writing Parse AST\n"); + rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_PARSE, db->parse->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write parse ast\n"); + goto exit; + } + +exit: + return rc; +} + +int cil_write_build_ast(FILE *out, cil_db_t *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Building AST from Parse Tree\n"); + rc = cil_build_ast(db, db->parse->root, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to build ast\n"); + goto exit; + } + + cil_log(CIL_INFO, "Destroying Parse Tree\n"); + cil_tree_destroy(&db->parse); + + cil_log(CIL_INFO, "Writing Build AST\n"); + rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_BUILD, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write build ast\n"); + goto exit; + } + +exit: + return rc; +} + +int cil_write_resolve_ast(FILE *out, cil_db_t *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Building AST from Parse Tree\n"); + rc = cil_build_ast(db, db->parse->root, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to build ast\n"); + goto exit; + } + + cil_log(CIL_INFO, "Destroying Parse Tree\n"); + cil_tree_destroy(&db->parse); + + cil_log(CIL_INFO, "Resolving AST\n"); + rc = cil_resolve_ast(db, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve ast\n"); + goto exit; + } + + cil_log(CIL_INFO, "Qualifying Names\n"); + rc = cil_fqn_qualify(db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to qualify names\n"); + goto exit; + } + + cil_log(CIL_INFO, "Writing Resolve AST\n"); + rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_RESOLVE, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write resolve ast\n"); + goto exit; + } + +exit: + return rc; +} + int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db) { int rc; diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in index eb572125..2e503bd1 100644 --- a/libsepol/src/libsepol.map.in +++ b/libsepol/src/libsepol.map.in @@ -269,4 +269,7 @@ LIBSEPOL_1.1 { LIBSEPOL_3.0 { global: sepol_policydb_optimize; + cil_write_parse_ast; + cil_write_build_ast; + cil_write_resolve_ast; } LIBSEPOL_1.1; -- 2.26.3