eclair: Add initial scripts and configs for the ECLAIR MISRA analysis tool
Scripts and configs are imported from the private prototype repository used
during initial stages of development. They are in turn based on
scripts/configs provided by Bugseng (ECLAIR vendor), as used in their
demo job for TF-A: https://eclairit.com:8443/job/TF-A/
Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
Change-Id: I10fbb55859beda7c9a6c36cdb202bcbd70bf95b7
diff --git a/eclair/MISRA_C_2012_selection.ecl b/eclair/MISRA_C_2012_selection.ecl
new file mode 100644
index 0000000..047dafc
--- /dev/null
+++ b/eclair/MISRA_C_2012_selection.ecl
@@ -0,0 +1,201 @@
+-project_name=getenv("ECLAIR_PROJECT_NAME")
+-project_root=getenv("ECLAIR_PROJECT_ROOT")
+
+-setq=data_dir,getenv("ECLAIR_DATA_DIR")
+
+-enable=B.REPORT.ECB
+-config=B.REPORT.ECB,output=join_paths(data_dir,"FRAME.@FRAME@.ecb")
+-config=B.REPORT.ECB,preprocessed=show
+-config=B.REPORT.ECB,macros=10
+-config=B.REPORT.ECB,tags=show
+
+-enable=B.EXPLAIN
+
+-doc_begin="See https://developer.trustedfirmware.org/w/tf_a/tf-a-misra-analysis/"
+# "Any implementation-defined behaviour on which the output of the program depends shall be documented and understood."
+# This requires configuring gazillion of generic parameters, where relation is mostly
+# not configured == warning, configured == no warning. Return to this later.
+#-enable=MC3R1.D1.1
+-enable=MC3R1.D2.1
+-enable=MC3R1.D4.1
+-enable=MC3R1.D4.2
+-enable=MC3R1.D4.3
+-enable=MC3R1.D4.4
+-doc="'Information' reports apply to #ifdef'ed code, don't show real problems, just add noise."
+-config=MC3R1.D4.4,reports+={hide,"kind(information)"}
+-enable=MC3R1.D4.5
+-enable=MC3R1.D4.7
+-enable=MC3R1.D4.10
+-enable=MC3R1.D4.11
+-enable=MC3R1.D4.12
+-enable=MC3R1.D4.13
+-enable=MC3R1.D4.14
+-enable=MC3R1.R1.1
+
+-enable=MC3R1.R1.2
+-doc_begin="TODO: Contains bare instances of __builtin_offsetof, should be wrapped in macro"
+-config=MC3R1.R1.2,reports+={todo,"all_area(all_loc(^include/drivers/console_assertions.h$))"}
+-config=MC3R1.R1.2,reports+={todo,"all_area(all_loc(^include/common/ep_info.h$))"}
+-doc_end
+
+-enable=MC3R1.R1.3
+
+-enable=MC3R1.R2.1
+-doc="When logging is disabled, no_tf_log() is expected to contain special unreachable code pattern."
+-config=MC3R1.R2.1,reports+={safe,"any_area(all_loc(macro(^no_tf_log$)))"}
+-doc="Silence warning about unreachable null statement. TODO: Better wrap macro in do {...} while (0) pattern."
+-config=MC3R1.R2.1,reports+={safe,"any_area(kind(culprit)&&^null statement is unreachable$)"}
+
+-enable=MC3R1.R2.2
+-enable=MC3R1.R2.3
+-enable=MC3R1.R2.6
+-enable=MC3R1.R3.1
+-enable=MC3R1.R3.2
+-enable=MC3R1.R4.1
+-enable=MC3R1.R4.2
+-enable=MC3R1.R5.2
+-enable=MC3R1.R5.3
+-enable=MC3R1.R5.4
+-enable=MC3R1.R5.5
+-enable=MC3R1.R5.6
+-enable=MC3R1.R5.7
+-enable=MC3R1.R5.9
+-enable=MC3R1.R6.1
+-enable=MC3R1.R6.2
+-enable=MC3R1.R7.1
+-enable=MC3R1.R7.2
+-enable=MC3R1.R7.3
+-enable=MC3R1.R7.4
+-enable=MC3R1.R8.1
+-enable=MC3R1.R8.2
+-enable=MC3R1.R8.3
+-enable=MC3R1.R8.4
+-enable=MC3R1.R8.5
+-enable=MC3R1.R8.8
+-enable=MC3R1.R8.9
+-enable=MC3R1.R8.10
+
+-enable=MC3R1.R8.11
+-doc="This macro intended to deal with special linker-defined symbols like __TEXT_START__"
+-config=MC3R1.R8.11,reports+={safe,"all_area(all_loc(macro(^IMPORT_SYM$)))"}
+
+-enable=MC3R1.R8.12
+-enable=MC3R1.R8.13
+-enable=MC3R1.R8.14
+-enable=MC3R1.R9.1
+-enable=MC3R1.R9.2
+-enable=MC3R1.R9.3
+-enable=MC3R1.R9.4
+-enable=MC3R1.R9.5
+-enable=MC3R1.R10.1
+-enable=MC3R1.R10.2
+-enable=MC3R1.R10.3
+-enable=MC3R1.R10.4
+-enable=MC3R1.R10.5
+-enable=MC3R1.R10.6
+-enable=MC3R1.R10.7
+-enable=MC3R1.R10.8
+-enable=MC3R1.R11.1
+-enable=MC3R1.R11.2
+-enable=MC3R1.R11.3
+-enable=MC3R1.R11.6
+-enable=MC3R1.R11.7
+-enable=MC3R1.R11.8
+-enable=MC3R1.R11.9
+-enable=MC3R1.R12.1
+-enable=MC3R1.R12.2
+-enable=MC3R1.R12.3
+-enable=MC3R1.R12.4
+-enable=MC3R1.R12.5
+-enable=MC3R1.R13.1
+-enable=MC3R1.R13.2
+-enable=MC3R1.R13.3
+-enable=MC3R1.R13.4
+-enable=MC3R1.R13.5
+-enable=MC3R1.R13.6
+-enable=MC3R1.R14.1
+-enable=MC3R1.R14.2
+
+-enable=MC3R1.R14.3
+-doc="When logging is disabled, no_tf_log() is expected to contain special unreachable code pattern."
+-config=MC3R1.R14.3,reports+={safe,"any_area(all_loc(macro(^no_tf_log$)))"}
+
+-enable=MC3R1.R14.4
+-enable=MC3R1.R15.2
+-enable=MC3R1.R15.3
+-enable=MC3R1.R15.4
+-enable=MC3R1.R15.7
+-enable=MC3R1.R16.2
+-enable=MC3R1.R16.4
+-enable=MC3R1.R16.5
+-enable=MC3R1.R16.6
+-enable=MC3R1.R16.7
+-enable=MC3R1.R17.2
+-enable=MC3R1.R17.3
+-enable=MC3R1.R17.4
+-enable=MC3R1.R17.5
+-enable=MC3R1.R17.6
+-enable=MC3R1.R17.7
+-enable=MC3R1.R17.8
+-enable=MC3R1.R18.1
+-enable=MC3R1.R18.2
+-enable=MC3R1.R18.3
+-enable=MC3R1.R18.4
+-enable=MC3R1.R18.5
+-enable=MC3R1.R18.6
+-enable=MC3R1.R18.7
+-enable=MC3R1.R18.8
+-enable=MC3R1.R19.1
+-enable=MC3R1.R19.2
+-enable=MC3R1.R20.1
+-enable=MC3R1.R20.2
+-enable=MC3R1.R20.3
+-enable=MC3R1.R20.4
+-enable=MC3R1.R20.5
+-enable=MC3R1.R20.6
+-enable=MC3R1.R20.7
+-enable=MC3R1.R20.8
+-enable=MC3R1.R20.9
+-enable=MC3R1.R20.10
+-enable=MC3R1.R20.11
+-enable=MC3R1.R20.12
+-enable=MC3R1.R20.13
+-enable=MC3R1.R20.14
+-enable=MC3R1.R21.1
+
+-enable=MC3R1.R21.2
+-doc="This macro intended to deal with special linker-defined symbols like __TEXT_START__"
+-config=MC3R1.R21.2,reports+={safe,"all_area(all_loc(macro(^IMPORT_SYM$)))"}
+
+-enable=MC3R1.R21.3
+-enable=MC3R1.R21.4
+-enable=MC3R1.R21.5
+-enable=MC3R1.R21.7
+-enable=MC3R1.R21.8
+-enable=MC3R1.R21.9
+-enable=MC3R1.R21.10
+-enable=MC3R1.R21.11
+-enable=MC3R1.R21.12
+-enable=MC3R1.R21.13
+-enable=MC3R1.R21.14
+-enable=MC3R1.R21.15
+-enable=MC3R1.R21.16
+-enable=MC3R1.R21.17
+-enable=MC3R1.R21.18
+-enable=MC3R1.R21.19
+-enable=MC3R1.R21.20
+-enable=MC3R1.R22.1
+-enable=MC3R1.R22.2
+-enable=MC3R1.R22.3
+-enable=MC3R1.R22.4
+-enable=MC3R1.R22.5
+-enable=MC3R1.R22.6
+-enable=MC3R1.R22.7
+-enable=MC3R1.R22.8
+-enable=MC3R1.R22.9
+-enable=MC3R1.R22.10
+-doc_end
+
+-eval_file=common_config.ecl
+
+-reports={hide,all_exp_external}
diff --git a/eclair/analyze.sh b/eclair/analyze.sh
new file mode 100755
index 0000000..666a79b
--- /dev/null
+++ b/eclair/analyze.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+#
+# Copyright (c) 2021-2022 BUGSENG srl. All rights reserved.
+# Copyright (c) 2022 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Stop immediately if any executed command has exit status different from 0.
+set -ex
+
+usage() {
+ echo "Usage: analyze.sh CONF" 1>&2
+ echo " where CONF is the build configuration id passed to build.sh" 1>&2
+}
+
+if [ $# -ne 1 ]
+then
+ usage
+ exit 1
+fi
+
+# Absolute path of the ECLAIR bin directory.
+ECLAIR_BIN_DIR="/opt/bugseng/eclair/bin"
+
+# Directory where this script resides: usually in a directory named "ECLAIR".
+SCRIPT_DIR="$(cd "$(dirname "$0")" ; echo "${PWD}")"
+
+# Directory where to put all ECLAIR output and temporary files.
+ECLAIR_OUTPUT_DIR="${WORKSPACE}/ECLAIR/out"
+
+export CROSS_COMPILE="/opt/gcc-arm-11.2-2022.02-x86_64-aarch64-none-elf/bin/aarch64-none-elf-"
+
+PLAT="$1"
+
+export CC_ALIASES="${CROSS_COMPILE}gcc"
+export CXX_ALIASES="${CROSS_COMPILE}g++"
+export LD_ALIASES="${CROSS_COMPILE}ld"
+export AR_ALIASES="${CROSS_COMPILE}ar"
+export AS_ALIASES="${CROSS_COMPILE}as"
+export FILEMANIP_ALIASES="cp mv ${CROSS_COMPILE}objcopy"
+
+which ${CROSS_COMPILE}gcc
+${CROSS_COMPILE}gcc -v
+
+# ECLAIR binary data directory and workspace.
+export ECLAIR_DATA_DIR="${ECLAIR_OUTPUT_DIR}/.data"
+# ECLAIR workspace.
+export ECLAIR_WORKSPACE="${ECLAIR_DATA_DIR}/eclair_workspace"
+# Destination file for the ECLAIR diagnostics.
+export ECLAIR_DIAGNOSTICS_OUTPUT="${ECLAIR_OUTPUT_DIR}/DIAGNOSTICS.txt"
+
+# Identifies the particular build of the project.
+export ECLAIR_PROJECT_NAME="TF_A_${PLAT}"
+# All paths mentioned in ECLAIR reports that are below this directory
+# will be presented as relative to ECLAIR_PROJECT_ROOT.
+export ECLAIR_PROJECT_ROOT="${WORKSPACE}/trusted-firmware-a"
+
+# Erase and recreate the output directory and the data directory.
+rm -rf "${ECLAIR_OUTPUT_DIR}"
+mkdir -p "${ECLAIR_DATA_DIR}"
+
+(
+ # Perform the build (from scratch) in an ECLAIR environment.
+ "${ECLAIR_BIN_DIR}/eclair_env" \
+ "-eval_file='${SCRIPT_DIR}/MISRA_C_2012_selection.ecl'" \
+ -- "${SCRIPT_DIR}/build-tfa.sh" "${PLAT}"
+)
+
+# Create the project database.
+PROJECT_ECD="${ECLAIR_OUTPUT_DIR}/PROJECT.ecd"
+find "${ECLAIR_DATA_DIR}" -maxdepth 1 -name "FRAME.*.ecb" \
+ | sort | xargs cat \
+ | "${ECLAIR_BIN_DIR}/eclair_report" \
+ "-create_db='${PROJECT_ECD}'" \
+ -load=/dev/stdin
+
+
+function make_self_contained() {
+ dir=$1
+ mkdir -p $dir/lib
+
+ cp -r /opt/bugseng/eclair-3.12.0/lib/html $dir/lib
+
+ ${SCRIPT_DIR}/relativize_urls.py $dir
+}
+
+${ECLAIR_BIN_DIR}/eclair_report -db=${PROJECT_ECD} \
+ -summary_txt=${ECLAIR_OUTPUT_DIR}/../summary_txt \
+ -full_txt=${ECLAIR_OUTPUT_DIR}/../full_txt \
+ -full_html=${ECLAIR_OUTPUT_DIR}/../full_html
+
+# summary_txt contains just a single report file not present in full_txt, move it there and be done with it.
+mv ${ECLAIR_OUTPUT_DIR}/../summary_txt/by_service.txt ${ECLAIR_OUTPUT_DIR}/../full_txt/
+rm -rf ${ECLAIR_OUTPUT_DIR}/../summary_txt
+make_self_contained ${ECLAIR_OUTPUT_DIR}/../full_html
+
+# Create the Jenkins reports file.
+JENKINS_XML="${ECLAIR_OUTPUT_DIR}/../jenkins.xml"
+${ECLAIR_BIN_DIR}/eclair_report -db=${PROJECT_ECD} -reports_jenkins=${JENKINS_XML}
+
+
+# Compress database to take less disk space in Jenkins archive
+xz ${PROJECT_ECD}
diff --git a/eclair/analyze_delta.sh b/eclair/analyze_delta.sh
new file mode 100755
index 0000000..f611169
--- /dev/null
+++ b/eclair/analyze_delta.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+#
+# Copyright (c) 2021-2022 BUGSENG srl. All rights reserved.
+# Copyright (c) 2022 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Stop immediately if any executed command has exit status different from 0.
+set -ex
+
+usage() {
+ echo "Usage: analyze.sh CONF" 1>&2
+ echo " where CONF is the build configuration id passed to build.sh" 1>&2
+}
+
+if [ $# -ne 1 ]
+then
+ usage
+ exit 1
+fi
+
+# Absolute path of the ECLAIR bin directory.
+ECLAIR_BIN_DIR="/opt/bugseng/eclair/bin"
+
+# Directory where this script resides: usually in a directory named "ECLAIR".
+SCRIPT_DIR="$(cd "$(dirname "$0")" ; echo "${PWD}")"
+
+export CROSS_COMPILE="/opt/gcc-arm-11.2-2022.02-x86_64-aarch64-none-elf/bin/aarch64-none-elf-"
+
+PLAT="$1"
+
+export CC_ALIASES="${CROSS_COMPILE}gcc"
+export CXX_ALIASES="${CROSS_COMPILE}g++"
+export LD_ALIASES="${CROSS_COMPILE}ld"
+export AR_ALIASES="${CROSS_COMPILE}ar"
+export AS_ALIASES="${CROSS_COMPILE}as"
+export FILEMANIP_ALIASES="cp mv ${CROSS_COMPILE}objcopy"
+
+# Identifies the particular build of the project.
+export ECLAIR_PROJECT_NAME="TF_A_${PLAT}"
+# All paths mentioned in ECLAIR reports that are below this directory
+# will be presented as relative to ECLAIR_PROJECT_ROOT.
+export ECLAIR_PROJECT_ROOT="${WORKSPACE}/trusted-firmware-a"
+
+
+function do_analyze() {
+
+ # ECLAIR binary data directory and workspace.
+ export ECLAIR_DATA_DIR="${ECLAIR_OUTPUT_DIR}/.data"
+ # ECLAIR workspace.
+ export ECLAIR_WORKSPACE="${ECLAIR_DATA_DIR}/eclair_workspace"
+ # Destination file for the ECLAIR diagnostics.
+ export ECLAIR_DIAGNOSTICS_OUTPUT="${ECLAIR_OUTPUT_DIR}/DIAGNOSTICS.txt"
+
+ # Erase and recreate the output directory and the data directory.
+ rm -rf "${ECLAIR_OUTPUT_DIR}"
+ mkdir -p "${ECLAIR_DATA_DIR}"
+
+ (
+ # Perform the build (from scratch) in an ECLAIR environment.
+ "${ECLAIR_BIN_DIR}/eclair_env" \
+ "-eval_file='${SCRIPT_DIR}/MISRA_C_2012_selection.ecl'" \
+ -- "${SCRIPT_DIR}/build-tfa.sh" "${PLAT}"
+ )
+
+ # Create the project database.
+ PROJECT_ECD="${ECLAIR_OUTPUT_DIR}/PROJECT.ecd"
+ find "${ECLAIR_DATA_DIR}" -maxdepth 1 -name "FRAME.*.ecb" \
+ | sort | xargs cat \
+ | "${ECLAIR_BIN_DIR}/eclair_report" \
+ "-create_db='${PROJECT_ECD}'" \
+ -load=/dev/stdin
+
+
+ function make_self_contained() {
+ dir=$1
+ mkdir -p $dir/lib
+
+ cp -r /opt/bugseng/eclair-3.12.0/lib/html $dir/lib
+
+ ${SCRIPT_DIR}/relativize_urls.py $dir
+ }
+
+ ${ECLAIR_BIN_DIR}/eclair_report -db=${PROJECT_ECD} \
+ -summary_txt=${ECLAIR_OUTPUT_DIR}/../summary_txt \
+ -full_txt=${ECLAIR_OUTPUT_DIR}/../full_txt \
+ -full_html=${ECLAIR_OUTPUT_DIR}/../full_html
+
+ # summary_txt contains just a single report file not present in full_txt, move it there and be done with it.
+ mv ${ECLAIR_OUTPUT_DIR}/../summary_txt/by_service.txt ${ECLAIR_OUTPUT_DIR}/../full_txt/
+ rm -rf ${ECLAIR_OUTPUT_DIR}/../summary_txt
+ make_self_contained ${ECLAIR_OUTPUT_DIR}/../full_html
+
+ # Create the Jenkins reports file.
+ JENKINS_XML="${ECLAIR_OUTPUT_DIR}/../jenkins.xml"
+ ${ECLAIR_BIN_DIR}/eclair_report -db=${PROJECT_ECD} -reports_jenkins=${JENKINS_XML}
+
+}
+
+# Directory where to put all ECLAIR output and temporary files.
+ECLAIR_OUTPUT_DIR="${WORKSPACE}/ECLAIR/out"
+
+do_analyze
+
+ECLAIR_OUTPUT_DIR="${WORKSPACE}/ECLAIR_BASE/out"
+
+(
+ cd ${ECLAIR_PROJECT_ROOT}
+ git checkout HEAD^
+ git log --oneline -n5
+)
+
+do_analyze
+
+diff -I '^Timestamp:' -x frames.txt -x files.txt -x explain.txt \
+ -ur ${WORKSPACE}/ECLAIR_BASE/summary_txt/ ${WORKSPACE}/ECLAIR/summary_txt/ > ${WORKSPACE}/ECLAIR/summary_txt.diff || true
+
+
+(
+${ECLAIR_BIN_DIR}/eclair_report -diff_criteria=fingerprint -diff_full_txt=ECLAIR_BASE/out/PROJECT.ecd,ECLAIR/out/PROJECT.ecd
+ls -l diff_output
+
+eclair_report -db=ECLAIR_BASE/out/PROJECT.ecd -sel_tag_glob=new,diff,missing -full_html=resolved_issues_html
+make_self_contained resolved_issues_html
+
+eclair_report -db=ECLAIR/out/PROJECT.ecd -sel_tag_glob=new,diff,missing -full_html=new_issues_html
+make_self_contained new_issues_html
+
+xz ECLAIR_BASE/out/PROJECT.ecd ECLAIR/out/PROJECT.ecd
+)
+
+${SCRIPT_DIR}/eclair_diff_report.py diff_output > misra_delta.txt
+
+
+cat <<EOF >index.html
+<html>
+<body>
+<h1>MISRA Delta reports for the patch</h1>
+<li><a href="misra_delta.txt">Cumulative TXT report</a>
+<li><a href="diff_output/">Per MISRA rule TXT reports</a>
+<li><a href="new_issues_html/by_service.html#first_file/service&kind">New issues, groupped per file changed (HTML).</a>
+<li><a href="resolved_issues_html/by_service.html#first_file/service&kind">Resolved issues, groupped per file changed (HTML).</a>
+</body>
+</html>
+EOF
diff --git a/eclair/build-tfa.sh b/eclair/build-tfa.sh
new file mode 100755
index 0000000..7954f6e
--- /dev/null
+++ b/eclair/build-tfa.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+#
+# Copyright (c) 2021-2022 BUGSENG srl. All rights reserved.
+# Copyright (c) 2022 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -ex
+
+export CROSS_COMPILE=/opt/gcc-arm-11.2-2022.02-x86_64-aarch64-none-elf/bin/aarch64-none-elf-
+cd ${WORKSPACE}/trusted-firmware-a
+make PLAT=$1 clean
+make PLAT=$1 ${MAKE_TARGET} -j3
diff --git a/eclair/common_config.ecl b/eclair/common_config.ecl
new file mode 100644
index 0000000..c8e1b8f
--- /dev/null
+++ b/eclair/common_config.ecl
@@ -0,0 +1,40 @@
+-eval_file=toolchain.ecl
+
+-eval_file=public_APIs.ecl
+-public_files+=api:public
+
+-doc_begin="Treat LIBC as external, as they have many peculiar declarations leading to spurious warnings."
+-file_tag+={external, "^include/lib/libc/.*$"}
+-file_tag+={external, "^lib/libc/.*$"}
+-doc_end
+
+-file_tag+={external, "^lib/compiler-rt/.*$"}
+-file_tag+={external, "^include/lib/libfdt/.*$"}
+-file_tag+={external, "^lib/libfdt/.*$"}
+
+-doc="Build version file is autogenerated and piped directly to compiler, captured by ECLAIR as /dev/pipe/XXX, changing from build to build, leading to spurious diffs."
+#-file_tag+={external, "^_ROOT/dev/pipe/.*$"}
+#-file_tag+={external, "^/dev/pipe/.*$"}
+-source_files={hide, "^/dev/pipe/.*$"}
+
+-doc="FIXME: cite the compiler manual section describing support for __asm__."
+-config=MC3R1.R1.2,reports+={hide,"category(^STD.tokenext/__asm__$)"}
+
+-doc="FIXME: cite the compiler manual section describing support for __attribute__."
+-config=MC3R1.R1.2,reports+={hide,"category(^STD.tokenext/__attribute__$)"}
+
+-doc="FIXME: cite the compiler manual section describing support for __typeof__."
+-config=MC3R1.R1.2,reports+={hide,"category(^STD.tokenext/__typeof__$)"}
+
+-doc_begin="Unless specified otherwise, a function with a non-const pointer argument is assumed not to read the pointee before writing it and it is assumed to write something to it before returning."
+-default_call_properties+="pointee_read(1..=never)"
+-default_call_properties+="pointee_write(1..=always)"
+-doc_end
+
+
+-doc="Unless specified otherwise, a function is assumed to not save/preserve the pointers received as arguments."
+-default_call_properties+="taken()"
+
+-remap_rtag={safe, hide}
+# Hide known TODOs for now
+-remap_rtag={todo, hide}
diff --git a/eclair/public_APIs.ecl b/eclair/public_APIs.ecl
new file mode 100644
index 0000000..e4931a0
--- /dev/null
+++ b/eclair/public_APIs.ecl
@@ -0,0 +1,5 @@
+# Definition of the public APIs.
+
+
+-doc="FIXME: add proper documentation."
+-file_tag+={api:public,"^include/arch/aarch64/arch\\.h$"}
diff --git a/eclair/report.ecl b/eclair/report.ecl
new file mode 100644
index 0000000..c41aad1
--- /dev/null
+++ b/eclair/report.ecl
@@ -0,0 +1,22 @@
+# eclair_report
+
+#defun(sel_violations(s),
+# create_sel(s,
+# [["clear_all",s],
+# ["add_kind",s,"violation"],
+# ["add_kind",s,"error"],
+# ["select_kind","",s],
+# ["reset",s],
+# ["add_service_glob",s,"B.EXPLAIN"],
+# ["select_service","",s]]),
+# sel(s))
+#
+#defun(sel_samples(s,count,domain1,domain2),
+# untag("sample","true"),
+# tag_samples("sample","true",count,domain1,domain2),
+# sel_tag_glob(s,"sample","true"),
+# sel(s))
+#
+#sel_violations("violations_selection")
+#sel_samples("samples_selection",20,"first_file","service")
+#save_sel()
diff --git a/eclair/toolchain.ecl b/eclair/toolchain.ecl
new file mode 100644
index 0000000..d7787c1
--- /dev/null
+++ b/eclair/toolchain.ecl
@@ -0,0 +1,13 @@
+# Compilers.
+-file_tag+={GCC,"^/opt/gcc-arm-.+/bin/aarch64-none-elf-gcc$"}
+
+-config=STD.tokenext,+behavior={c99, GCC, "^(__asm|__asm__|__attribute__|__restrict|__typeof__|__builtin_types_compatible_p|__builtin_offsetof|__volatile__|__alignof|_Static_assert)$"}
+-config=STD.inclnest,+behavior={c99, GCC, 24}
+-config=STD.ppifnest,+behavior={c99, GCC, 32}
+-config=STD.macident,+behavior={c99, GCC, 4096}
+-config=STD.stdtypes,+behavior={c99, GCC, "unsigned long long||long long"}
+
+-config=STD.charsmem,+behavior={c99, GCC, utf8}
+-config=STD.bytebits,+behavior={c99, GCC, 8}
+-config=STD.freesten,+behavior={c99, GCC, specified}
+-config=STD.freestnd,+behavior={c99, GCC, specified}