[PATCH v3] Eclair: scan the last xen-syms linking pass on Arm

Dmytro Prokopchuk1 posted 1 patch 22 hours ago
.../eclair_analysis/ECLAIR/analysis.ecl       |  2 +-
.../ECLAIR/generate-xen-syms-passes.sh        | 20 +++++++++++++++++++
.../eclair_analysis/ECLAIR/generate_ecl.sh    |  3 +++
3 files changed, 24 insertions(+), 1 deletion(-)
create mode 100755 automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
[PATCH v3] Eclair: scan the last xen-syms linking pass on Arm
Posted by Dmytro Prokopchuk1 22 hours ago
The hide pattern .xen-syms.[013] leaves pass 2 visible. On x86
LAST_LINKING_PASS is 2, so that is the final link. On Arm
LAST_LINKING_PASS is 3 and the final image is .xen-syms.3. Pass 2 is
usually only a symlink, so Eclair saw no program link and reported every
translation unit as unreachable.

During analysis preparation, read LAST_LINKING_PASS from the architecture
makefile and the pass numbers from the foreach list in
xen/scripts/Makefile.link. Hide every pass except that one. An earlier
pass that is a real link stays hidden. The generator runs from
generate_ecl.sh, together with the other ECLAIR configuration scripts.

Fixes: a401b5c9dc35 ("Eclair: re-enable scanning of the (almost) final linking step")
Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
---
Test CI pipeline: https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/2940065908

Changes in v3:
- generate the hide pattern from generate_ecl.sh, which prepare.sh already runs

Link to v2:
https://patchew.org/Xen/e73c282694e68083305d03219f983bf74a8bf494.1791392326.git.dmytro._5Fprokopchuk1@epam.com/

Changes in v2:
- update commit message
- generate hide pattern before analysis
- read LAST_LINKING_PASS from the arch Makefile and pass numbers from the Makefile.link
---
 .../eclair_analysis/ECLAIR/analysis.ecl       |  2 +-
 .../ECLAIR/generate-xen-syms-passes.sh        | 20 +++++++++++++++++++
 .../eclair_analysis/ECLAIR/generate_ecl.sh    |  3 +++
 3 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100755 automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh

diff --git a/automation/eclair_analysis/ECLAIR/analysis.ecl b/automation/eclair_analysis/ECLAIR/analysis.ecl
index c6e1a7a95d..df1006bcaa 100644
--- a/automation/eclair_analysis/ECLAIR/analysis.ecl
+++ b/automation/eclair_analysis/ECLAIR/analysis.ecl
@@ -37,7 +37,7 @@ their Standard Library equivalents."
 -doc_begin="Do not analyze intermediate linking artifacts, as they do not differ from their final
 counterparts for the purposes of MISRA C static analysis."
 -file_tag+={xen_efi_tmp, "^xen/\\.xen\\.efi\\.([01]|alt\\..*)$"}
--file_tag+={xen_syms_tmp, "^xen/\\.xen-syms\\.[013]$"}
+-eval_file=xen_syms_passes.ecl
 -frames+={hide, "kind(program)&&target(xen_syms_tmp||xen_efi_tmp)"}
 -doc_end
 
diff --git a/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
new file mode 100755
index 0000000000..e3795e8234
--- /dev/null
+++ b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Hide every xen-syms linking pass except LAST_LINKING_PASS.
+# The pass list is the foreach in xen/scripts/Makefile.link.
+
+set -e
+
+cd "$(dirname "$0")"
+arch=$(echo "${XEN_TARGET_ARCH}" | sed -e 's/x86.*/x86/' -e 's/arm.*/arm/')
+last=$(sed -n 's/^LAST_LINKING_PASS *:= *\([0-9]\).*/\1/p' \
+    "../../../xen/arch/${arch}/Makefile" | head -n 1)
+passes=$(sed -n 's/.*foreach n,\([0-9 ]*\).*/\1/p' \
+    ../../../xen/scripts/Makefile.link | head -n 1)
+test -n "${last}"
+test -n "${passes}"
+hidden=$(printf '%s' "${passes}" | tr -d " ${last}")
+
+printf '%s\n' \
+    "-file_tag+={xen_syms_tmp, \"^xen/\\\\.xen-syms\\\\.[${hidden}]\$\"}" \
+    >xen_syms_passes.ecl
diff --git a/automation/eclair_analysis/ECLAIR/generate_ecl.sh b/automation/eclair_analysis/ECLAIR/generate_ecl.sh
index b955783904..b97fc55fd2 100755
--- a/automation/eclair_analysis/ECLAIR/generate_ecl.sh
+++ b/automation/eclair_analysis/ECLAIR/generate_ecl.sh
@@ -20,3 +20,6 @@ accepted_rst="${ECLAIR_PROJECT_ROOT}/docs/misra/rules.rst"
 
 # Generate the list of linker-defined symbols (must be run after a Xen build)
 "${script_dir}/generate-linker-symbols.sh"
+
+# Hide every xen-syms linking pass except LAST_LINKING_PASS.
+"${script_dir}/generate-xen-syms-passes.sh"
-- 
2.43.0
Re: [PATCH v3] Eclair: scan the last xen-syms linking pass on Arm
Posted by Nicola Vetrini 6 hours ago
On 2026-10-12 22:49, Dmytro Prokopchuk1 wrote:
> The hide pattern .xen-syms.[013] leaves pass 2 visible. On x86
> LAST_LINKING_PASS is 2, so that is the final link. On Arm
> LAST_LINKING_PASS is 3 and the final image is .xen-syms.3. Pass 2 is
> usually only a symlink, so Eclair saw no program link and reported 
> every
> translation unit as unreachable.
> 
> During analysis preparation, read LAST_LINKING_PASS from the 
> architecture
> makefile and the pass numbers from the foreach list in
> xen/scripts/Makefile.link. Hide every pass except that one. An earlier
> pass that is a real link stays hidden. The generator runs from
> generate_ecl.sh, together with the other ECLAIR configuration scripts.
> 
> Fixes: a401b5c9dc35 ("Eclair: re-enable scanning of the (almost) final 
> linking step")
> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>

Acked-by: Nicola Vetrini <nicola.vetrini@bugseng.com>

Thanks for spotting and fixing this!

> ---
> Test CI pipeline: 
> https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/2940065908
> 
> Changes in v3:
> - generate the hide pattern from generate_ecl.sh, which prepare.sh 
> already runs
> 
> Link to v2:
> https://patchew.org/Xen/e73c282694e68083305d03219f983bf74a8bf494.1791392326.git.dmytro._5Fprokopchuk1@epam.com/
> 
> Changes in v2:
> - update commit message
> - generate hide pattern before analysis
> - read LAST_LINKING_PASS from the arch Makefile and pass numbers from 
> the Makefile.link
> ---
>  .../eclair_analysis/ECLAIR/analysis.ecl       |  2 +-
>  .../ECLAIR/generate-xen-syms-passes.sh        | 20 +++++++++++++++++++
>  .../eclair_analysis/ECLAIR/generate_ecl.sh    |  3 +++
>  3 files changed, 24 insertions(+), 1 deletion(-)
>  create mode 100755 
> automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
> 
> diff --git a/automation/eclair_analysis/ECLAIR/analysis.ecl 
> b/automation/eclair_analysis/ECLAIR/analysis.ecl
> index c6e1a7a95d..df1006bcaa 100644
> --- a/automation/eclair_analysis/ECLAIR/analysis.ecl
> +++ b/automation/eclair_analysis/ECLAIR/analysis.ecl
> @@ -37,7 +37,7 @@ their Standard Library equivalents."
>  -doc_begin="Do not analyze intermediate linking artifacts, as they do 
> not differ from their final
>  counterparts for the purposes of MISRA C static analysis."
>  -file_tag+={xen_efi_tmp, "^xen/\\.xen\\.efi\\.([01]|alt\\..*)$"}
> --file_tag+={xen_syms_tmp, "^xen/\\.xen-syms\\.[013]$"}
> +-eval_file=xen_syms_passes.ecl
>  -frames+={hide, "kind(program)&&target(xen_syms_tmp||xen_efi_tmp)"}
>  -doc_end
> 
> diff --git 
> a/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh 
> b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
> new file mode 100755
> index 0000000000..e3795e8234
> --- /dev/null
> +++ b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
> @@ -0,0 +1,20 @@
> +#!/bin/bash
> +
> +# Hide every xen-syms linking pass except LAST_LINKING_PASS.
> +# The pass list is the foreach in xen/scripts/Makefile.link.
> +
> +set -e
> +
> +cd "$(dirname "$0")"
> +arch=$(echo "${XEN_TARGET_ARCH}" | sed -e 's/x86.*/x86/' -e 
> 's/arm.*/arm/')
> +last=$(sed -n 's/^LAST_LINKING_PASS *:= *\([0-9]\).*/\1/p' \
> +    "../../../xen/arch/${arch}/Makefile" | head -n 1)
> +passes=$(sed -n 's/.*foreach n,\([0-9 ]*\).*/\1/p' \
> +    ../../../xen/scripts/Makefile.link | head -n 1)
> +test -n "${last}"
> +test -n "${passes}"
> +hidden=$(printf '%s' "${passes}" | tr -d " ${last}")
> +
> +printf '%s\n' \
> +    "-file_tag+={xen_syms_tmp, 
> \"^xen/\\\\.xen-syms\\\\.[${hidden}]\$\"}" \
> +    >xen_syms_passes.ecl
> diff --git a/automation/eclair_analysis/ECLAIR/generate_ecl.sh 
> b/automation/eclair_analysis/ECLAIR/generate_ecl.sh
> index b955783904..b97fc55fd2 100755
> --- a/automation/eclair_analysis/ECLAIR/generate_ecl.sh
> +++ b/automation/eclair_analysis/ECLAIR/generate_ecl.sh
> @@ -20,3 +20,6 @@ 
> accepted_rst="${ECLAIR_PROJECT_ROOT}/docs/misra/rules.rst"
> 
>  # Generate the list of linker-defined symbols (must be run after a Xen 
> build)
>  "${script_dir}/generate-linker-symbols.sh"
> +
> +# Hide every xen-syms linking pass except LAST_LINKING_PASS.
> +"${script_dir}/generate-xen-syms-passes.sh"

-- 
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
Re: [PATCH v3] Eclair: scan the last xen-syms linking pass on Arm
Posted by Jan Beulich 11 hours ago
On 12.10.2026 22:49, Dmytro Prokopchuk1 wrote:
> --- /dev/null
> +++ b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh

You neatly use dashes in the new file's name here. Is there a reason ...

> @@ -0,0 +1,20 @@
> +#!/bin/bash
> +
> +# Hide every xen-syms linking pass except LAST_LINKING_PASS.
> +# The pass list is the foreach in xen/scripts/Makefile.link.
> +
> +set -e
> +
> +cd "$(dirname "$0")"
> +arch=$(echo "${XEN_TARGET_ARCH}" | sed -e 's/x86.*/x86/' -e 's/arm.*/arm/')
> +last=$(sed -n 's/^LAST_LINKING_PASS *:= *\([0-9]\).*/\1/p' \
> +    "../../../xen/arch/${arch}/Makefile" | head -n 1)
> +passes=$(sed -n 's/.*foreach n,\([0-9 ]*\).*/\1/p' \
> +    ../../../xen/scripts/Makefile.link | head -n 1)
> +test -n "${last}"
> +test -n "${passes}"
> +hidden=$(printf '%s' "${passes}" | tr -d " ${last}")
> +
> +printf '%s\n' \
> +    "-file_tag+={xen_syms_tmp, \"^xen/\\\\.xen-syms\\\\.[${hidden}]\$\"}" \
> +    >xen_syms_passes.ecl

... underscores are used here?

Jan
Re: [PATCH v3] Eclair: scan the last xen-syms linking pass on Arm
Posted by Dmytro Prokopchuk1 10 hours ago

On 10/13/26 10:52, Jan Beulich wrote:
> On 12.10.2026 22:49, Dmytro Prokopchuk1 wrote:
>> --- /dev/null
>> +++ b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
> 
> You neatly use dashes in the new file's name here. Is there a reason ...
> 
>> @@ -0,0 +1,20 @@
>> +#!/bin/bash
>> +
>> +# Hide every xen-syms linking pass except LAST_LINKING_PASS.
>> +# The pass list is the foreach in xen/scripts/Makefile.link.
>> +
>> +set -e
>> +
>> +cd "$(dirname "$0")"
>> +arch=$(echo "${XEN_TARGET_ARCH}" | sed -e 's/x86.*/x86/' -e 's/arm.*/arm/')
>> +last=$(sed -n 's/^LAST_LINKING_PASS *:= *\([0-9]\).*/\1/p' \
>> +    "../../../xen/arch/${arch}/Makefile" | head -n 1)
>> +passes=$(sed -n 's/.*foreach n,\([0-9 ]*\).*/\1/p' \
>> +    ../../../xen/scripts/Makefile.link | head -n 1)
>> +test -n "${last}"
>> +test -n "${passes}"
>> +hidden=$(printf '%s' "${passes}" | tr -d " ${last}")
>> +
>> +printf '%s\n' \
>> +    "-file_tag+={xen_syms_tmp, \"^xen/\\\\.xen-syms\\\\.[${hidden}]\$\"}" \
>> +    >xen_syms_passes.ecl
> 
> ... underscores are used here?
> 
> Jan

The generated file follows the other .ecl names (e.g. 
linker_symbols.ecl). The script name follows generate-linker-symbols.sh, 
which also uses dashes and writes an .ecl file with underscores.

BR,
Dmytro
Re: [PATCH v3] Eclair: scan the last xen-syms linking pass on Arm
Posted by Jan Beulich 10 hours ago
On 13.10.2026 10:02, Dmytro Prokopchuk1 wrote:
> On 10/13/26 10:52, Jan Beulich wrote:
>> On 12.10.2026 22:49, Dmytro Prokopchuk1 wrote:
>>> --- /dev/null
>>> +++ b/automation/eclair_analysis/ECLAIR/generate-xen-syms-passes.sh
>>
>> You neatly use dashes in the new file's name here. Is there a reason ...
>>
>>> @@ -0,0 +1,20 @@
>>> +#!/bin/bash
>>> +
>>> +# Hide every xen-syms linking pass except LAST_LINKING_PASS.
>>> +# The pass list is the foreach in xen/scripts/Makefile.link.
>>> +
>>> +set -e
>>> +
>>> +cd "$(dirname "$0")"
>>> +arch=$(echo "${XEN_TARGET_ARCH}" | sed -e 's/x86.*/x86/' -e 's/arm.*/arm/')
>>> +last=$(sed -n 's/^LAST_LINKING_PASS *:= *\([0-9]\).*/\1/p' \
>>> +    "../../../xen/arch/${arch}/Makefile" | head -n 1)
>>> +passes=$(sed -n 's/.*foreach n,\([0-9 ]*\).*/\1/p' \
>>> +    ../../../xen/scripts/Makefile.link | head -n 1)
>>> +test -n "${last}"
>>> +test -n "${passes}"
>>> +hidden=$(printf '%s' "${passes}" | tr -d " ${last}")
>>> +
>>> +printf '%s\n' \
>>> +    "-file_tag+={xen_syms_tmp, \"^xen/\\\\.xen-syms\\\\.[${hidden}]\$\"}" \
>>> +    >xen_syms_passes.ecl
>>
>> ... underscores are used here?
> 
> The generated file follows the other .ecl names (e.g. 
> linker_symbols.ecl). The script name follows generate-linker-symbols.sh, 
> which also uses dashes and writes an .ecl file with underscores.

That's not very nice, but otoh not as problematic to warrant an immediate
change. At the same time here your use of underscores is not only a style
issue (where bad pre-existing instances should never be used as an excuse),
but also weakens the connection to xen-syms: The underscore used could in
principle be a surrogate for about any non-alnum character, including e.g.
a dot.

Jan