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

Build failure of TF-A v2.11 under Buildroot #26

Open
vstehle opened this issue Sep 2, 2024 · 6 comments
Open

Build failure of TF-A v2.11 under Buildroot #26

vstehle opened this issue Sep 2, 2024 · 6 comments

Comments

@vstehle
Copy link
Contributor

vstehle commented Sep 2, 2024

Switching from TF-A v2.10 to v2.11 can cause build issues under Buildroot.

In some cases, the link fails with the following error:

bl1.elf: error: PHDR segment not covered by LOAD segment

This can be reproduced with the following commands:

git clone https://gitlab.com/buildroot.org/buildroot.git -b 2024.08-rc3
cd buildroot
make qemu_aarch64_ebbr_defconfig
sed -i 's/v2.10/v2.11/' .config
make arm-trusted-firmware

(To confirm that v2.10 is indeed building fine, just omit the line with the sed command. The file output/images/bl1.bin should be produced.)

The issue seems to be caused by the switch from ld to gcc for the link of TF-A bl1, combined with the fact that Buildroot uses a toolchain wrapper with PIE related flags.

@jolivain
Copy link

jolivain commented Sep 2, 2024

Hi @vstehle,

I'm currently able to fix this issue with the following Buildroot TF-A build recipe patch:
jolivain/buildroot@fa3fd91
See the commit log for my current analysis.

I believe this patch will be needed in Buildroot anyways because it needs to compile many TF-A different versions, ranging from v2.0 to 2.10 and hopefully v2.11 soon. So even if there is an improvement in TF-A, it will appear in newer versions only. I need to run some more tests to check if my patch is not breaking anything (in older TF-A version) before sending it.

Detecting PIE just by looking at the "gcc -v" output might have some limitation. See here:
https://git.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a.git/+/refs/tags/v2.11.0/Makefile#711

Maybe one way to improve could be to enhance the "PIE_FOUND" detection (by compiling a small test program) or to provide a variable to declare that the toolchain will do PIE (e.g. TOOLCHAIN_GENERATES_PIE=1) that will override the PIE_FOUND detection?

@vstehle
Copy link
Contributor Author

vstehle commented Sep 3, 2024

Thanks @jolivain; I confirm your patch allows to build v2.11 with Buildroot.

@jolivain
Copy link

jolivain commented Sep 3, 2024

Hi @vstehle, thanks testing! I'll add a Tested-by: tag when I'll submit my patch. I'm still running regression testing on all defconfigs that include a version of TF-A... Hopefully, I'll send the patch later today.

@jolivain
Copy link

jolivain commented Sep 3, 2024

For info, I proposed a patch in Buildroot here:
https://patchwork.ozlabs.org/project/buildroot/patch/[email protected]/

arnout pushed a commit to buildroot/buildroot that referenced this issue Sep 3, 2024
Arm Trusted Firmware (TF-A) v2.11 fails to build in some situations
with the error message:

    ld: build/qemu/release/bl1/bl1.elf: error: PHDR segment not covered by LOAD segment

This error can be reproduced with the commands:

    make qemu_aarch64_ebbr_defconfig
    utils/config --set-str BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE v2.11
    make olddefconfig
    make

This issue was reported in [1].

This error is coming from a check that was made more strict since
binutils ld 2.34. This error message is normally related to dynamic
linker, so it should normally not apply to a package like TF-A.

When BR2_SHARED_LIBS=y (shared libraries only) and BR2_PIC_PIE=y
(Build code with PIC/PIE), the Buildroot toolchain-wrapper will try
to enable position-independent code/executables. See [2]. This
configuration is a common default.

Arm Trusted Firmware (TF-A) build system, on its side, tries to detect
if the toolchain enables PIE automatically. It does so by checking if
--enable-default-pie is in the output of "$(CC) -v". If found, the TF-A
build system tries to disable PIE globally (it can be explicitly
enabled again with the ENABLE_PIE=1 build variable, in some specific
configurations). This detection mechanism is not working with the
Buildroot toolchain wrapper which is enabling PIE silently. See [3].

Commit 1061ed6 "boot/arm-trusted-firmware: add -fno-PIE to CFLAGS"
added the option -fno-PIE in CFLAGS for that reason. See [4].
TF-A >= v2.11 now needs the same treatment for LDFLAGS. This is
because TF-A switched the default linker from "ld" to "gcc", in
upstream commit [5]. This change makes the Buildroot toolchain wrapper
to enable PIE at link, without passing the "--no-dynamic-linker" option
that would normally avoids this ld error.

Also, even if there is no defconfigs using the
BR2_TARGET_ARM_TRUSTED_FIRMWARE_LATEST_VERSION config directive, it is
worth mentioning that the Buildroot TF-A "latest version" was updated
to v2.11 in commit 9c50759 "boot/arm-trusted-firmware: bump to
v2.11". See [6]. This latest version is the default choice. So
Buildroot is subject to generate this build failure. This can be
reproduced with the commands:

    cat <<EOF >.config
    BR2_aarch64=y
    BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
    BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="qemu"
    BR2_TOOLCHAIN_EXTERNAL=y
    EOF
    make olddefconfig
    make arm-trusted-firmware

This commit fixes the issue by adding the option "-no-pie" in LDFLAGS.
This will prevent the Buildroot toolchain wrapper to enable PIE, for
versions using "gcc" as a linker. This change should also remain
compatible with older TF-A < 2.11 using "ld" as a linker, since
"-no-pie" is also a valid ld option.

Fixes:

    ld: build/qemu/release/bl1/bl1.elf: error: PHDR segment not covered by LOAD segment

[1] TrustedFirmware-A/trusted-firmware-a#26
[2] https://gitlab.com/buildroot.org/buildroot/-/blob/2024.08-rc3/toolchain/toolchain-wrapper.c?ref_type=tags#L403
[3] https://git.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a.git/+/refs/tags/v2.11.0/Makefile#711
[4] https://gitlab.com/buildroot.org/buildroot/-/commit/1061ed6c6273e90618b05ddc0cb66be17364da33
[5] https://git.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a.git/+/2f1c5e7eb1775b252fa4998e10093b8ac34ca699%5E%21/
[6] https://gitlab.com/buildroot.org/buildroot/-/commit/9c50759cd1677e1739078239a1e86fb1d62e33e8

Reported-by: Vincent Stehlé <[email protected]>
Tested-by: Vincent Stehlé <[email protected]>
Signed-off-by: Julien Olivain <[email protected]>
Signed-off-by: Yann E. MORIN <[email protected]>
@odeprez
Copy link
Contributor

odeprez commented Sep 6, 2024

Hi @jolivain thanks for digging and fixing into buildroot build system. What is the way forward? Do you expect further refinement on TF-A build flow side?

@CJKay
Copy link
Member

CJKay commented Oct 25, 2024

This appears to have cropped up again with Buildroot: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/31746

I'm wondering whether we should be trying to detect this from the default toolchain configuration at all. An alternative approach would be to compile a test C file that compiles successfully only if the __PIE__ preprocessor definition is defined, then set the default value for ENABLE_PIE based on that, e.g.

// check_pie.c

#ifndef __PIE
#       error "PIE not found"
#endif

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

4 participants